索引是以必定數據格式存儲數據的查找路徑的數據形式。mysql
這裏舉個例子:sql
最典型的就是圖書館找一本書,咱們能夠經過 「文學」 -> 「當代」 -> 「散文」 來縮小咱們要找某一本書的範圍。那麼在這裏書本的大分類、時代、小分類,就能夠做爲找書本的索引。mysql優化
索引很消耗資源,不添加沒必要要的索引。這裏是由於,索引是以樹結構來存儲的,爲了加快檢索的效率,減小查詢的次數,mysql須要保證這個樹的平衡,而這須要花銷比較多的資源和時間。性能
對於寫:索引的更新每每是最主要的開銷。那麼,對於寫異常頻繁的業務,咱們能夠考慮刪除索引這種很是規的手段。優化
對於讀:索引會佔用內存跟硬盤空間。佔用內存和硬盤的同時,也加快了檢索的速度,典型的以空間換時間的作法。spa
1.本質上沒差異,「AAAA」 < 「AAAB」(collation)
2.LIKE是特殊的範圍查詢
3.LIKE 「ABC%」 等同於「ABC[LOWEST]」<KEY<「ABC[HIGHEST]」,因爲前綴確認,可使用索引
4.LIKE 「%ABC」沒法使用索引code
1.數據按主鍵彙集。也就是說,根據主鍵能夠直接獲取數據。
2.主鍵隱藏添加在全部索引的後面,也就是說 KEY(A)等同於KEY(A,ID)blog
下面語句可使用索引 (LAST_NAME)排序
SELECT * FROM EMPLOYEES WHERE LAST_NAME=「Smith」
下面語句可以使用索引 (DEPT,LAST_NAME)索引
SELECT * FROM EMPLOYEES WHERE LAST_NAME=「Smith」 AND DEPT=「Accounting」
考慮有索引 (A,B,C),請留意字段的順序
如下狀況可以使用索引
A>5 //用到了(A) A=5 AND B>6 //用到了(A,B) A=5 AND B=6 AND C=7 //用到了(A,B,C) A=5 AND B IN (2,3) AND C>5 //用到了(A,B,C)
如下狀況不夠使用索引
B>5 B=6 AND C=7
如下狀況只能使用到索引的部分字段
//只能用上index(A) A>5 AND B=2 //只能用上index(A,B) A=5 AND B>6 AND C=2
多字段索引結論
1.索引的匹配規則是左匹配的
2.有了(A,B,C),就等於同時擁有了(A)和(A,B)
3.只要索引內,開始用範圍查詢,後面的索引就失效了。
這裏注意:
IN 在 where 中,也屬於準確查詢,不會使後面索引失效。
下面語句可使用索引 (SCORE)
SELECT * FROM PLAYERS ORDER BY SCORE DESC LIMIT 10
下面語句可以使用索引 (COUNTRY, SCORE)
SELECT * FROM PLAYERS WHERE COUNTRY=「US」 ORDER BY SCORE DESC LIMIT 10
考慮有索引(A, B),留意字段順序
如下狀況可以使用索引
ORDER BY A A=5 ORDER BY B ORDER BY A DESC, B DESC A>5 ORDER BY A
如下狀況不能使用索引用於排序
ORDER BY B //第二個字段上面排序 A>5 ORDER BY B //第一個字段是範圍查詢 A IN(1,2) ORDER BY B //第一個字段是IN範圍查詢 ORDER BY A ASC, B DESC //排序字段的順序不一致
對於一個索引來講,裏面的索引是有前後順序的。
例如:索引(A,B,C)
系統創建索引時,mysql會這麼作:
首先,會根據 A 的值,構建索引,
在相同 A 索引下,創建 B 的索引,
在 B 相同的索引下,創建 C 的單獨索引。
再多的字段也是如此類推。
索引組內,當前索引沒法在前綴不肯定的狀況下使用當前索引。
這也就是下面這幾個語句沒法使用索引或沒法使用完整索引的緣由:
A LIKE '%aaa' //前綴不肯定,沒法使用索引 A>5 AND B=2 //前綴A不肯定,只能用到 (A),沒法用(A,B) A IN(1,2) ORDER BY B //只能用到 (A),沒法用(A,B)
那爲何「A=5 AND B IN (2,3) AND C>5」 能夠用到(A,B,C)呢?
實際上,mysql優化器在這裏作了優化,
查詢的時候拆分了兩次檢查索引:
A=5 AND B=2 AND C>5 A=5 AND B=3 AND C>5
那麼,在IN的範圍不太大的狀況下,能夠在很大程度上優化查詢速度。
1.每次查詢動態選擇
2.估算走索引須要查詢的行數
3.根據「Cardinality」的狀態。做爲重要參考標準。大體原理是:索引重疊的程度,重疊程度越低,這個基數越大,優化器優先選取。
show index from table 執行結果
Cardinality - 圖2
此圖告訴咱們:
使用索引查找速度對比爲:customer_id > i_gid > company_id
1.給最頻繁的語句加索引 --要總體來看,而不是一條一條語句添加
2.儘量擴展索引,而不是新增索引
3.WHERE條件跟JOIN都能用上索引是最好的,
4.新增索引後要驗證索引是否生效,是否對能提高性能
例子:
SELECT * FROM TBL WHERE A=5 AND B=6
SELECT * FROM TBL WHERE A>5 AND B=6
應該新增索引(B,A)
考慮索引(A,B),A 類型爲 int
//只能用到(A)索引 SELECT * FROM TBL WHERE A BETWEEN 2 AND 4 AND B=5
改成
//能夠用到整個索引 SELECT * FROM TBL WHERE A IN (2,3,4) AND B=5
考慮索引KEY (GENDER,CITY),GENDER性別爲可枚舉數據
//沒法使用索引 SELECT * FROM PEOPLE WHERE CITY=「NEW YORK」
改成
//能用索引 SELECT * FROM PEOPLE WHERE GENDER IN (「M」,」F」) AND CITY=「NEW
對於Gender, Status, Boolean 類型很是有效
考慮索引KEY(A,B)
//沒法使用索引 SELECT * FROM TBL WHERE A IN (1,2) ORDER BY B LIMIT 5;
改成
//能使用索引用做排序,沒有file_sort (SELECT * FROM TBL WHERE A=1 ORDER BY B LIMIT 5) UNION ALL (SELECT * FROM TBL WHERE A=2 ORDER BY B LIMIT 5) ORDER BY B LIMIT 5;
考慮索引KEY(A,B),KEY(C)
select * from tb where a=1 and b =2 order by c limit 10
有時候不能正確的選擇索引,
會指定使用索引(C),
先排序後篩選,致使全面檢索。
這時候須要指定索引或者改成
select * from tb where a=1 and b =2 order by c+0 limit 10
關於EXPLAIN語句,能夠幫助咱們去了解一條語句的執行效率和所用到的索引,因爲太複雜,能夠去自行看官方的文檔。有空能夠繼續寫一篇文章去幫助你們理解,也幫助本身總結。
做者:簡公介 連接:https://www.jianshu.com/p/d08f16867012 來源:簡書 簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。