---恢復內容開始---
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!=232; 5 命中,因為主鍵還是會走索引
>
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 變量名=值
無論是否有索引,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)