mysql - 索引優化

開發中可能會遇到索引失效的狀況,使用到了索引字段可是卻沒有利用索引查詢。mysql

創建一個測試用表sql

DROP TABLE IF EXISTS index_test;
CREATE TABLE index_test(
   t_id INT PRIMARY KEY,
   key1 INT,
   key2 INT,
   key3 INT,
   key4 INT,
   content VARCHAR(20)
);

INSERT INTO index_test VALUES(1,1,1,1,1,'a');
INSERT INTO index_test VALUES(2,1,2,3,4,'b');
INSERT INTO index_test VALUES(3,4,1,2,3,'c');
INSERT INTO index_test VALUES(4,3,4,1,2,'d');
INSERT INTO index_test VALUES(5,2,3,4,1,'e');


CREATE INDEX index_key1_key2_key3_key4 ON index_test(key1,key2,key3,key4);

 

如何防止索引失效:函數

1. 最佳左前綴法則: 索引爲多列時,查詢條件最好從索引最左邊開始,不跳過中間列。(不過能夠插入別的條件,好比key=1,content = ‘a’, key2 = 2 這樣,不會影響總體效率)測試

 

 

 使用的是查詢類型是ref(索引掃描),根據索引進行了常量查詢(索引的取值是個常數),查詢結果利用率是100%(只掃了符合條件的那一條數據)。優化

 

 

 

 當使用的查詢條件沒有從索引的第一列開始時,查詢類型變成了all(掃描全表),key = null (沒有用到索引),ref = null(沒有利用索引查詢), 查詢結果利用率只有20%(掃描了5行數據,只有一條符合條件。)spa

 

2. 不要在索引列上作任何操做(計算,函數,類型轉換,不等於,is null, is not null)3d

 

 

 把key = 1 變成了 key +1 = 2   結果同樣,可是查詢從索引查詢變成了全表掃描。code

 

3. 範圍查詢右邊的索引會失效。 blog

 

 

 此時是一個範圍查詢,並且效率很高。索引

 

 

 

當key2 後面 加了 key3後,雖然條件更加精確了,可是效率反而低了。 由於key3的索引沒有被使用,單獨爲key3進行了全表掃描。

因此這時最好創建索引順序 key1,key3,key2, 而後把範圍查詢放在最後。

 

4. 儘可能使用索引覆蓋, 少用 select * 查詢

 

 查詢內容中有不是索引的列(我這個表裏的content不是索引),則mysql會先找到符合條件的行,而後從表中讀取數據

  查詢的列所有是索引內的列(不是同一個索引裏的也能夠),則mysql會直接從索引中讀取數據。

 

 5. 通配符不要做爲字段開頭,不然會致使索引失效(like   '%aaa')

加一個key5用來測試

ALTER TABLE index_test ADD COLUMN key5 VARCHAR(20);
UPDATE index_test SET key5 = CONCAT('test_',content,key1);
CREATE INDEX index_key5 ON index_test(key5);

 

%放在後面,進行了索引key5的範圍搜索。 

 %放在前面,或者兩邊,進行了全表搜索

 

 

解決:在實際狀況中,不可避免會使用%在兩邊的狀況,這時能夠利用索引覆蓋提升效率

 

 建立複合索引key1,key2,key5,這樣查詢內容變爲包含key5的一個索引中的內容,查詢索引覆蓋,變爲索引查詢

 

 再加個 主鍵依然生效。 可是加其餘索引列就不能夠。

 

6. 新人殺手= =||   varchar字段沒加 ' ',大幅拖慢速度並且很難被發現。。。

 正常狀況: 索引查詢, 使用了key5, 常數查詢。

 好比有個‘2000’, 寫成了 2000, 則會索引失效。變成了全表搜索

 

7.儘可能不要用or。  

聽說舊版本會致使索引失效,我試着沒問題,貌似如今沒事了= =? 

這個通常是用union 或者 in 來優化。 

相關文章
相關標籤/搜索