python/MySQL(索引、執行計划、BDA、分頁)


---恢復內容開始---

python/MySQL(索引、執行計划、BDA、分頁)

MySQL索引:

 所謂索引的就是具有(約束和加速查找的一種方式)  

  創建索引的缺點是對數據進行(修改、更新、刪除)比較慢!

 索引共分為:

1、主鍵索引:

    特性:加速查找、不能為空、不能重復

2、普通索引:

    特性:加速查找

3、唯一索引:

    特性:加速查找、可以為空、不能重復

4、聯合索引:

    特征:(多列)聯合主鍵索引、聯合唯一索引、聯合普通索引

5、全文索引:

    特征:對文本的內容進行分詞,進行搜索

索引用途及案例:

在頻繁查找使用的數據進行創建索引   

加速查找:

通過設置得索引去查找速度較快;

例如:  

 1 mysql> select * from useru where uname='alex23232';
 2 +-------+-----------+---------------+--------+
 3 | id    | uname     | emlia         | gender |
 4 +-------+-----------+---------------+--------+
 5 | 23232 | alex23232 | 23232@.qq.com | 男     |
 6 +-------+-----------+---------------+--------+
 7 1 row in set (0.04 sec)
 8 ===========================================
 9 
10 上邊是通過索引查找,速度快!
11 
12 ===========================================
13 mysql> select * from useru where emlia='23423@.qq.com';
14 +-------+-----------+---------------+--------+
15 | id    | uname     | emlia         | gender |
16 +-------+-----------+---------------+--------+
17 | 23423 | alex23423 | 23423@.qq.com | 男     |
18 +-------+-----------+---------------+--------+
19 1 row in set (0.18 sec)
20 ==========================================
21 上邊的就是沒有通過索引進行查找,速度較慢!

 

無索引:是從前到后依次查找(那樣相當於手中拿着一本厚厚的新華字典,如果想要查看數據就要從頭一直翻到數據那頁)

有索引:是從特殊符索引表里找到相應的位置,然后再找到數據存放在硬盤的位置。

索引類型:

hash索引: 這是一種索引方式,它把數據表中的設置為索引的哪一列轉換成hash值開辟一個新的表格進行存儲,當要進行索引查詢時就去新開辟的表格中查找相應的存儲部位。(hash很適合找單獨數據,在找范圍內的數據比較慢!)

btree索引:也稱為二叉樹索引,在數據庫中默認使用 (范圍內可以快速查找!)

索引的操作:

創建普通索引:

1 create index in_de on useru(uname);
2 create index 索引名  on 需要創建的表名(表列)

 

創建唯一索引:

1 create unique index in_ss on useru(uname)

 

唯一索引比普通的索引要快(因為普通的索引會出現重復)

創建組合索引:(最左前綴匹配)

1 create index index__s on useru(uname,emali);
2 組合索引需要遵循最左前綴匹配
3 例如:
4 select * from useru where unaem='alex212132';   這樣就是在執行索引查詢 (命中)
5 select * from useru where emali='234322@.qq.com';     這樣的就沒有執行索引查詢(未命中)
6 select * from useru where uname='alex2323' and emali='234234242@.11.com';                              這樣就是在執行索引查詢(命中)

索引合並:

1 create index in_s on useru(uname);
2 create index in_c on useru(emali);
3 分別設置倆個索引,把他們合並進行查找;
4 select * from useru where uname='alex1212' and emali='9439493@.qq.com';
5 select * from useru where emali='67453345@.qq.com'
6 組合索引沒有最左前綴的限制

 

覆蓋索引:

1 select uname from useru where uname='alex232343';
2 在索引文件中直接獲取數據

 

命中索引:

like

1 like ‘al%0’
2 select * from useru where unaem like 'a%0';
未命中索

 使用函數

1 mysql> select * from useru where reverse(uname)='0324xela';
2 +------+----------+--------------+--------+
3 | id   | uname    | emlia        | gender |
4 +------+----------+--------------+--------+
5 | 4230 | alex4230 | 4230@.qq.com | 男     |
6 +------+----------+--------------+--------+
7 1 row in set (12.59 sec)
8 
9 未命中

 or 未命中

 1 mysql> select * from useru where emlia='234234@.qq.com' or uname='alex23432';
 2 +--------+------------+----------------+--------+
 3 | id     | uname      | emlia          | gender |
 4 +--------+------------+----------------+--------+
 5 |  23432 | alex23432  | 23432@.qq.com  | 男     |
 6 | 234234 | alex234234 | 234234@.qq.com | 男     |
 7 +--------+------------+----------------+--------+
 8 2 rows in set (0.05 sec)
 9 
10 mysql> select * from useru where uname='alex23432';
11 +-------+-----------+---------------+--------+
12 | id    | uname     | emlia         | gender |
13 +-------+-----------+---------------+--------+
14 | 23432 | alex23432 | 23432@.qq.com | 男     |
15 +-------+-----------+---------------+--------+
16 1 row in set (0.00 sec)
17 未命中,因為查詢當中有未創建索引導致加速失敗

 

 or 命中

1 mysql> select * from useru where id='323423' or uname='alex23432';
2 +--------+------------+----------------+--------+
3 | id     | uname      | emlia          | gender |
4 +--------+------------+----------------+--------+
5 |  23432 | alex23432  | 23432@.qq.com  | 男     |
6 | 323423 | alex323423 | 323423@.qq.com | 男     |
7 +--------+------------+----------------+--------+
8 2 rows in set (0.04 sec)
9 命中,因為倆個都設置了索引,加速成功

 

 類型不一樣

1 mysql> select * from useru where uname=3432;
2 Empty set, 65535 warnings (13.03 sec)

 

 != (不等於)

1 select * from useru where uname!='alex122';
2 未命中,因為需要進行匹配
3 
4 select * from uname where id!=2325 命中,因為主鍵還是會走索引

 

 >

1 select * from useru where uname > 'alex232'
2 未命中,因為設置索引不是整型
3 
4 select * from useru where id > 3232;
5 命中,因為id是整型,如果設置的索引是整型就會加速;

 

order by

1 select * from useru order by uname desc;
2 未命中,因為根據排序時候,選擇的映射如果不是索引,則不走索引
3 select * from useru order by id desc;

 

組合索引最左前綴

1 如果組合索引為:(name,email)
2 name and email  -- 使用索引
3 name                 -- 使用索引
4 email                -- 不使用索引

 

 其他注意事項:

避免使用select *

count(1)或count(列)代替count(*)

創建表時盡量 char 代替 vachar

表的字段順序固定長度的字段優先

組合索引代替多個單列索引(經常使用多個條件查詢時)

盡量使用短索引

使用連接(join)來代替子查詢(sub-queries)

連表時注意條件類型需一致

索引散列值(重復少)不適合建索引,例:性別不適合

  

執行計划:

explain  +sql語句  用於顯示sql執行信息參數,根據參數信息可以進行sql優化(模擬出運行時間)
1 mysql> explain select * from useru;
2 +----+-------------+-------+------------+------+---------------+------+---------+------+---------+----------+-------+
3 | id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows    | filtered | Extra |
4 +----+-------------+-------+------------+------+---------------+------+---------+------+---------+----------+-------+
5 |  1 | SIMPLE      | useru | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 1835575 |   100.00 | NULL  |
6 +----+-------------+-------+------------+------+---------------+------+---------+------+---------+----------+-------+
7 1 row in set, 1 warning (0.00 sec)
8 
9 主要是查看type類型

 

select——type   (查詢類型)

 1 SIMPLE    簡單查詢
 2 
 3 PRIMARY  最外層查詢
 4 
 5 SUBQUERY  映射為子查詢
 6 
 7 DERIVED    子查詢
 8 
 9 UNION      聯合
10 
11 UNION RESULT  使用聯合的結果
12 table   正在訪問的表名
13 
14  type
15 
16 查詢時分的訪問方式,性能:all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const
17 
18 ALL 全表掃描,對於數據表從頭到尾找一遍
19 
20    特別的:如果limit限制,則找到之后就不在繼續向下掃描
21 
22    雖然上述倆個語言都會進行全表掃描,第二句使用了limit 則找到一個后就不在繼續查找
23 
24 index   全索引掃描,對索引從頭到尾字找一遍
25 
26    select id from useru;
27 
28 ret 根據索引查找一個或多個值
29 
30    select * from useru where uname='alex12122l;
31 
32  
33 
34  EQ_REF  連接時使用primary key 或unique類型
35 
36     select useru.id,useru.uname from useru left join usert on useru.id=usert.nid;
37 
38  
39 
40  const  常量:
41 
42        表最多有一個匹配行,因為僅有一行,在這行的列值可被優化器剩余部分認為是常數,const表很快,因為只讀取一次
43 
44     system  系統
45 
46        表僅有一行(=系統表)這是const連接類型的一個特例。
47 
48     select * from(select id from uname where id =1)as A;
49 
50  
51 
52  possible_keys
53 
54   可以使用的索引
55 
56 key
57 
58   真實使用的
59 
60 key_len
61 
62    MySQL中使用索引字節長度
63 
64 rows
65 
66   MYSQL 估計為了找到所需的行兒要讀取的行數---------只是預估值
67 
68 extra 該列包含MySQL解決查詢的詳細信息
69 
70    “Using index”
71 
72      此值表示mysql將使用覆蓋索引,以避免訪問表。不要把覆蓋索引和index訪問類型弄混了。
73 
74   “Using where”
75 
76     這意味着mysql服務器將在存儲引擎檢索行后再進行過濾,許多where條件里涉及索引中的列,當(並且如果)它讀取索引時,就能被存儲引擎檢驗,因此不是所有帶where子句的查詢都會顯示“Using where”。有時“Using where”的出現就是一個暗示:查詢可受益於不同的索引。
77 
78    “Using temporary”
79 
80     這意味着mysql在對查詢結果排序時會使用一個臨時表。 “Using filesort” 這意味着mysql會對結果使用一個外部索引排序,而不是按索引次序從表里讀取行。mysql有兩種文件排序算法,這兩種排序方式都可以在內存或者磁盤上完成,explain不會告訴你mysql將使用哪一種文件排序,也不會告訴你排序會在內存里還是磁盤上完成。
81 
82   “Range checked for each record(index map: N)”
83 
84     這個意味着沒有好用的索引,新的索引將在聯接的每一行上重新估算,N是顯示在possible_keys列中索引的位圖,並且是冗余的。

慢日志查詢:

配置MySQL自動記錄慢日志
1 1 slow _query_log=OFF       是否開啟慢日志記錄
2 2 long_query_time=2          時間限制,超過此時間,則記錄
3 3 slow_query_log_file=/usr/low/slow.log   日志文件
4 4 log_queseris_not_indexds=OFF    為使用索引的搜素是否記錄 
5 5 
6 6 注:查看當前配置信息:
7 7             show variables like ‘%query%8 8     修改當前配置:
9 9     set global 變量名=值
View Code

 

查看MySQL慢日志
1 mysqldumpslow -s at -a  /usr/local/var/mysql/MacBook-Pro-3-slow.log
 1 1 """
 2  2 --verbose    版本
 3  3 --debug      調試
 4  4 --help       幫助
 5  5  
 6  6 -v           版本
 7  7 -d           調試模式
 8  8 -s ORDER     排序方式
 9  9              what to sort by (al, at, ar, c, l, r, t), 'at' is default
10 10               al: average lock time
11 11               ar: average rows sent
12 12               at: average query time
13 13                c: count
14 14                l: lock time
15 15                r: rows sent
16 16                t: query time
17 17 -r           反轉順序,默認文件倒序拍。reverse the sort order (largest last instead of first)
18 18 -t NUM       顯示前N條just show the top n queries
19 19 -a           不要將SQL中數字轉換成N,字符串轉換成S。don't abstract all numbers to N and strings to 'S'
20 20 -n NUM       abstract numbers with at least n digits within names
21 21 -g PATTERN   正則匹配;grep: only consider stmts that include this string
22 22 -h HOSTNAME  mysql機器名或者IP;hostname of db server for *-slow.log filename (can be wildcard),
23 23              default is '*', i.e. match all
24 24 -i NAME      name of server instance (if using mysql.server startup script)
25 25 -l           總時間中不減去鎖定時間;don't subtract lock time from total time
26 26 """
View Code

limit 分頁:

 無論是否有索引,limit分頁是一個值得關注的問題:

 1 mysql> select * from useru limit 10,10;
 2 +----+--------+------------+--------+
 3 | id | uname  | emlia      | gender |
 4 +----+--------+------------+--------+
 5 | 11 | alex11 | 11@.qq.com | 男     |
 6 | 12 | alex12 | 12@.qq.com | 男     |
 7 | 13 | alex13 | 13@.qq.com | 男     |
 8 | 14 | alex14 | 14@.qq.com | 男     |
 9 | 15 | alex15 | 15@.qq.com | 男     |
10 | 16 | alex16 | 16@.qq.com | 男     |
11 | 17 | alex17 | 17@.qq.com | 男     |
12 | 18 | alex18 | 18@.qq.com | 男     |
13 | 19 | alex19 | 19@.qq.com | 男     |
14 | 20 | alex20 | 20@.qq.com | 男     |
15 +----+--------+------------+--------+
16 10 rows in set (0.00 sec)

 

 這樣如果數據多,查看的頁數越多就相當於掃描全部文件在限制的位置停止,這樣查詢還不是走到索引、

又要實現分頁功能還要走索引查詢:

 1 mysql>      select
 2     ->         *
 3     ->     from
 4     ->        useru
 5     ->     where
 6     ->         id < (select  id from (select id from useru where id < 970  order by id desc limit 40)as A order by A.id asc limit 1)
 7     ->     order by
 8     ->         id desc
 9     ->     limit 10;
10 +-----+---------+-------------+--------+
11 | id  | uname   | emlia       | gender |
12 +-----+---------+-------------+--------+
13 | 929 | alex929 | 929@.qq.com | 男     |
14 | 928 | alex928 | 928@.qq.com | 男     |
15 | 927 | alex927 | 927@.qq.com | 男     |
16 | 926 | alex926 | 926@.qq.com | 男     |
17 | 925 | alex925 | 925@.qq.com | 男     |
18 | 924 | alex924 | 924@.qq.com | 男     |
19 | 923 | alex923 | 923@.qq.com | 男     |
20 | 922 | alex922 | 922@.qq.com | 男     |
21 | 921 | alex921 | 921@.qq.com | 男     |
22 | 920 | alex920 | 920@.qq.com | 男     |
23 +-----+---------+-------------+--------+
24 10 rows in set (0.00 sec)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM