Cardinality數值表示了該索引字段的重複率程度,數值越大表明重複率越低,PRIMIARY是自增的,可以保證插入/更新數據按照磁盤順序進行,可是id字段由於沒有什麼可篩選的含義,不能進行篩選查詢。sql
咱們爲data_unique_key創建了一個惟一索引,這個屬性的值是一些篩選字段的md5值,若是是具體查詢某一條數據的話,能夠md5後查詢data_unique_key爲該值,速度很快。緩存
對於重複率很是大的字段,探索一下爲a創建索引是否有必要。
a的Cardinality是21
b的Cardinality是77
c的Cardinality是1305優化
ALTER TABLE test ADD INDEX index (a, b, c);
假設如今有一張test表,咱們先創建一個聯合索引,索引包含a,b,c3個字段。
咱們創建的索引是3個字段聯合的,可是查詢的時候只用兩個字段進行篩選,也會使用這個索引的前兩個字段進行篩選。
仍是使用兩個字段進行篩選,只是用了c而不是b,查詢使用了index這個索引可是key_len是202,說明只用了a的索引部分。這現象是「最左匹配原則」帶來的。也就是說要像最大化利用索引,篩選的時候要根據創建索引的字段順序就行查詢,若是where等篩選/分組/排序操做能命中索引的部分順序字段,則也會使用這部分順序字段進行索引。
SELECT中有索引的字段,優化器會選擇使用索引查詢,因此查詢出來的結果是以page_name排序的。
反之,若是SELECT中沒有索引字段,或者只有部分包含,或者是查詢 * ,都不會使用索引進行查詢spa
SELECT a, e FROM test WHERE a = '2';
(這個時間應該是利用了緩存的基礎上的時間,第一次進行全表查詢的時間是7秒多,一樣的sql再次查詢就變成了1+秒,試過將query_cache_type和query_cache_size都設置爲0,仍是這樣,有說法是操做系統級別的緩存是沒法限制的。若是一開始就創建索引,並SELECT a FROM test,也是六七秒,因此懷疑查詢後都會有緩存,那麼如下的時間都是在這個基礎上進行截圖)操作系統
創建一個聯合索引3d
ALTER TABLE test ADD INDEX index(`a, b, c`);
-- SQL1: SELECT a, e FROM test WHERE a = '1' ;
-- SQL2: SELECT a, e FROM test WHERE a = '1' AND b = 2;
-- SQL3: SELECT a, e FROM test WHERE a = '1' AND data_type = 2 AND c = 'math';
發現了只利用索引的一個字段進行查詢,查詢花費的時間比全表查詢還要慢不少,可是索引字段利用率大,查詢花費的時間就不多了。code
刪除上面創建的索引,再創建一個不包含a的索引blog
ALTER TABLE test DROP INDEX index, ADD INDEX index(b, c);
SQL1的執行以下:
至關於查詢type是all,耗時比以前的包含a索引的快
一樣的SQL2,能夠看到索引利用長度是1,可是速度是幾乎同樣的,這裏能夠看出來a的重複率過高,是索引這個字段的意義並不大,並且會增長索引key的長度,帶來B+Tree每個節點的鍵值存儲量減小,樹的結構可能會更深,進而查詢更慢。排序
總結:索引
(以上截圖都模糊掉自身數據,用a,b,c來代替)