索引長度短,區分度就低,索引長度長,區分度高,查詢效率高,可是索引要佔內存,因此要找到一個平衡點;sql
舉個例子: (張,張三,張三哥),若是索引長度取1的話,那麼每一行的索引都是 張 這個字,徹底沒有區分度,結果這樣三行徹底是隨機排的,由於索引都同樣;若是長度取2,那麼排序的時候至少前兩個是排對了的,若是取3,區分度達到100%,已經提早排序;數據庫
有一些特殊的字段好比url,絕大部分的url都是 http://www. 開頭的,這種狀況下索引長度取取到11都是無效的,須要更長的索引,那麼有沒有優雅的方式來解決呢;
第一種方法: 能夠將數據倒序存入數據庫;
第二種方法:對字符串進行crc32哈希處理;app
在多個Where條件的時候,會優先採用rows最少的索引。若是多個Where條件查詢很頻繁,則將where中全部字段加到聯合索引。
注意:函數
select * from tb where YEAR(data) < '2017'
; 可優化爲 data < CURDATE()select * from tb where key1 = xxx and key2 = xxx
或 select * from tb where key1 = xxx
會走複合索引,而 select * from tb where key2 = xxx
不會走複合索引。即最左前綴匹配。select * from tb col_1=2 or col_2=2
,應優化爲select * from tb where col_1=2 union select * from tb where col_2=2
。對於select key_1 from t where key_2 ·····;這樣的查詢,查詢的處理過程爲:首先去檢索key_2索引找到主鍵id,而後根據主鍵id去檢索正確的數據行。這樣就是兩次檢索。
將key_1和key_2加到聯合索引,InnoDB能夠直接在索引中獲取結果數據集,這就是索引覆蓋。優化
如下狀況,InnoDB沒法覆蓋查詢:
1 select選擇的字段中含有不在索引中的字段 ,也即索引沒有覆蓋所有的列。
2 where 條件中不能含有對索引進行like的操做。url
若是應用程序有不少 JOIN 查詢,你應該確認兩個表中Join的字段是被建過索引的。這樣,MySQL內部會啓動爲你優化Join的SQL語句的機制。Join的字段,應該是相同的類型的,對於STRING類型,還須要有相同的字符集才行。(兩個表的字符集有可能不同)code