高效的選擇和使用索引有很多方式,有的是針對特殊案例的優化方法,有的則是針對特定行為的優化,使用哪個索引,以及如何評估選擇不同索引的性能影響的技巧,則需要持續不斷地學習。(本文章需要一定索引基礎) 1.索引要是獨立的列 “獨立的列”是指索引列不能是表達式的一部分,也不能是函數的參數。例如,下麵這個查詢 ...
高效的選擇和使用索引有很多方式,有的是針對特殊案例的優化方法,有的則是針對特定行為的優化,使用哪個索引,以及如何評估選擇不同索引的性能影響的技巧,則需要持續不斷地學習。(本文章需要一定索引基礎)
1.索引要是獨立的列
“獨立的列”是指索引列不能是表達式的一部分,也不能是函數的參數。例如,下麵這個查詢無法使用actor_id列的索引
mysql>SELECT actor_id FROM sakila.actor WHERE actor_id + 1 = 5;
憑肉眼很容易看出WHERE中的表達式其實等價與 actor_id = 4,但是MySQL無法自動解析這個方程式。這完全是用戶行為。我們應該養成簡化WHERE條件的習慣,始終將索引列單獨放在比較符號的一側
下麵是另一個常見的錯誤:
mysql>SELECT ... WHERE TO_DAYS(CURRENT_DATE) - TO_DAYS(date_col) <= 10;
2.首碼索引和索引的選擇性
索引的選擇性:
索引的選擇性是指 不重覆的索引值(也稱之為基數)和數據表記錄總數(#T)的比值,範圍從1/#T到1之間。索引的選擇性越高則查詢效率越高。唯一索引的選擇性是一,這是最好的索引選擇性,性能也是最好的。
對於BLOB、TEXT或者很長的VARCHAR類型的列。必須使用首碼索引,因為mysql不允許索引這些列的完整長度。
首碼索引選擇首碼長度的訣竅在於選擇足夠長的首碼以保證較高的選擇性,通知用不能太長(以便節約空間),足夠長的長度以使得首碼索引的選擇性接近於索引的整個列
如何計算合適的首碼長度?
計算整列的選擇性,並使首碼的選擇性接近完成列的選擇性
計算完整列的選擇性
mysql>SELECT COUNT(DISTINCT city)/COUNT(*) city_demo;
計算不同首碼長度的選擇性:
mysql>SELECT COUNT(DISTINCT LEFT(city, 3))/COUNT(*) AS sel3,
COUNT(DISTINCT LEFT(city, 4))/COUNT(*) AS sel4,
COUNT(DISTINCT LEFT(city, 5))/COUNT(*) AS sel5,
COUNT(DISTINCT LEFT(city, 6))/COUNT(*) AS sel6,
COUNT(DISTINCT LEFT(city, 7))/COUNT(*) AS sel7,
FROM city_demo;
求出的首碼選擇性接近於完整列的選擇性基本上就可以用了,但要註意,只看平均選擇性是不夠的,也有例外的情況需要考慮最壞情況下的選擇性。
前面已經說明如何找到合適的首碼長度,下麵掩飾一下如何創建首碼索引
mysql>ALTER TABLE city_demo ADD KEY (city(7));