mysql索引(二)----如何高效使用索引
1、索引的優點
索引總結下來有三個:
- 索引大大減少了伺服器需要掃描的資料量。
- 索引可以幫助伺服器避免排序和臨時表。
- 索引可以將所及 I/O 變為順序 I/O。
2、高效使用索引
不恰當地使用索引,或者無法使用已有的索引,將無法使索引的優勢發揮出來。正確使用索引的方式可以非常高效地提高我們查詢的速度,下面是幾種高效使用索引的方式。
2.1 獨立的列
‘’獨立的列‘’是指索引列不能是表示式的一部分,也不能是函式的引數。
使用WHERE條件時,要始終將索引列單獨放在比較符號的一側。
例如,下面將無法使用 actor_id 列的索引:
mysql> SELECT actor_id FROM actor WHERE actor_id + 1 = 5;
憑肉眼很容易看出 actor_id = 4,但是MySQL 卻無法自動解析這個方程式,所以這個所以並沒有被用到。
2.2 字首索引和索引選擇性
索引的選擇性是指,不重複的索引值(也稱為基數)和資料表的記錄總數(#T)的比值,範圍是 1/#T 到 1 之間。
例如,求 actor_id 的基數:
mysql> SELECT COUNT(DISTINCT actor_id) / COUNT(*)
>FROM actor;
索引的選擇性越高則查詢效率越高,因為選擇性高的索引可以讓 MySQL 在查詢時過濾掉更多的行。唯一索引的選擇性是 1,這是最好的索引選擇性,效能也是最好的。
有時候需要索引很長的字元列,這會讓索引變得大且慢
訣竅在於要選擇足夠長的字首以保證較高的選擇性,同時又不能太長(以便節約空間)。換句話說,選擇的字首的“基數”應該接近於完整列的“基數”。
不過字首索引也有缺點:
- MySQL 無法使用字首索引做 ORDER BY 和 GROUP BY,也無法使用字首索引做覆蓋掃描。
2.3 多列索引
對於多列索引的理解,一個常見的錯誤就是,為每個列建立獨立的索引,或者按照錯誤的順序建立多列索引。
在多個列上建立獨立的單列索引大部分情況下並不能提高 MySQL 的查詢效能。
在 MySQL 5.0 之後,查詢能夠同時使用多個單列索引進行掃描,並將結果進行合併。這種演算法有三個變種:
- OR 條件的聯合(union)
- AND 條件的相交(intersection)
- 同時存在 OR 條件和 AND 條件
可以通過 EXPLAIN 中的 Extra 列看到:
索引合併策略有時候是一種優化的結果,但實際上更多時候說明了表上的索引建得很糟糕:
- 當多個索引做 AND 條件操作時,通常意味著需要一個包含所有相關列的多列索引,而不是多個獨立的單例索引。
- 當多個索引做 OR 條件操作時,通常需要耗費大量 CPU 和記憶體資源在演算法的快取、排序和合並操作上。特別是當其中有些索引的選擇性不高,需要合併掃描大量資料的時候。
- 更重要的是,優化器不會把這些計算到“查詢成本”中。所以通常來說,如果有多個單列索引進行查詢,將查詢改寫成 union 的方式往往更好。當然,最好的辦法還是將索引改寫成正確的多列索引。
2.4 選擇合適的索引列順序
在一個多列 B-Tree 索引中,索引列的順序意味著索引首先按照最左列進行排序,其次是第二列,等等。
索引可以按照升序或者降序進行掃描,以滿足精確符合列順序的 ORDER BY 、GROUP BY 和 DISTINCT 等子句的查詢需求,所以多列索引的列順序至關重要。
對於選擇索引列有一個經驗法則:將選擇性最高的列放在索引最前列。
但是這個並不是放之四海而皆準的法則,場景不同則選擇不同。
在不考慮排序和分組時,這個法則通常是很好的。