MySQL中的索引:
基本法則:索引應該構建在被用作查詢條件的字段上;
索引類型:
B+ Tree索引:順序存儲,每一個葉子節點到根結點的距離是相同的;左前綴索引,適合查詢範圍類的數據;
可以使用B-Tree索引的查詢類型:全鍵值、鍵值範圍或鍵前綴查找;
全值匹配:精確某個值, "Jinjiao King";
匹配最左前綴:只精確匹配起頭部分,"Jin%"
匹配範圍值:
精確匹配某一列並範圍匹配另一列:
只訪問索引的查詢
不適合使用B-Tree索引的場景:
如果不從最左列開始,索引無效; (Age,Name)
不能跳過索引中的列;(StuID,Name,Age)
如果查詢中某個列是爲範圍查詢,那麼其右側的列都無法再使用索引優化查詢;(StuID,Name)
Hash索引:基於哈希表實現,特別適用於精確匹配索引中的所有列;
注意:只有Memory存儲引擎支持顯式hash索引;
適用場景:
只支持等值比較查詢,包括=, IN(), <=>;
不適合使用hash索引的場景:
存儲的非爲值的順序,因此,不適用於順序查詢;
不支持模糊匹配;
空間索引(R-Tree):
MyISAM支持空間索引;
全文索引(FULLTEXT):
在文本中查找關鍵詞;
索引優點:
索引可以降低服務需要掃描的數據量,減少了IO次數;
索引可以幫助服務器避免排序和使用臨時表;
索引可以幫助將隨機I/O轉爲順序I/O;
高性能索引策略:
獨立使用列,儘量避免其參與運算;
左前綴索引:索引構建於字段的左側的多少個字符,要通過索引選擇性來評估
索引選擇性:不重複的索引值和數據表的記錄總數的比值;
多列索引:
AND操作時更適合使用多列索引;
選擇合適的索引列次序:將選擇性最高放左側;
冗餘和重複索引:
不好的索引使用策略
通過EXPLAIN來分析索引的有效性:
EXPLAIN SELECT clause
獲取查詢執行計劃信息,用來查看查詢優化器如何執行查詢;
mysql> EXPLAIN SELECT name from student WHERE id>10\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: student
type: range
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: NULL
rows: 8
Extra: Using where
1 row in set (0.00 sec)
輸出:
id: 當前查詢語句中,每個SELECT語句的編號;
複雜類型的查詢有三種:
簡單子查詢;
用於FROM中的子查詢;
聯合查詢:UNION;
注意:UNION查詢的分析結果會出現一外額外匿名臨時表;
select_type:
簡單查詢爲SIMPLE
複雜查詢:
SUBQUERY: 簡單子查詢;
DERIVED: 用於FROM中的子查詢;
UNION:UNION語句的第一個之後的SELECT語句;
UNION RESULT: 匿名臨時表;
table:SELECT語句關聯到的表;
type:關聯類型,或訪問類型,即MySQL決定的如何去查詢表中的行的方式;
ALL: 全表掃描;
index:根據索引的次序進行全表掃描;如果在Extra列出現“Using index”表示了使用覆蓋索引,而非全表掃描;
range:有範圍限制的根據索引實現範圍掃描;掃描位置始於索引中的某一點,結束於另一點;
ref: 根據索引返回表中匹配某單個值的所有行;
eq_ref:僅返回一個行,但與需要額外與某個參考值做比較;
const, system: 直接返回單個行;
NULL:類似於覆蓋查詢
possible_keys:查詢可能會用到的索引;
key: 查詢中使用了的索引;
key_len: 在索引使用的字節數;
ref: 在利用key字段所表示的索引完成查詢時所有的列或某常量值;const表示固定值
rows:MySQL估計爲找所有的目標行而需要讀取的行數;
Extra:額外信息
Using index:MySQL將會使用覆蓋索引,以避免訪問表;
Using where:MySQL服務器將在存儲引擎檢索後,再進行一次過濾;
Using temporary:MySQL對結果排序時會使用臨時表;
Using filesort:對結果使用一個外部索引排序;