《高效能MySQL》筆記-索引
什麼是索引,為什麼要使用索引
資料庫的索引,就像一本字典的索引一樣,可以讓你快速定位到你想尋找的地方。
索引可以大大加快查詢的速度。想想一下,如果一本字典沒有索引,想查一個東西只能從頭到尾“遍歷”整本字典,十分不方便。
雖然索引可以加快查詢速度。但是索引也要佔用一部分空間,因此索引不是越多越好。
對於重複資料比較多,選擇性高的列,不適合作為索引。(索引的選擇性:不重複的索引值和資料表的記錄總數的比值,即
索引底層的基本實現
- B-Tree(B+Tree)
基於樹的資料結構,可以進行值的範圍查詢,並且可以根據最左字首來進行匹配。 - Hash
基於Hash函式,定位資料特別快,但是由於進行Hash操作之後,資料的有序性被破壞,因此無法進行索引的範圍查詢,且不支援最左字首匹配。 - 空間資料索引
可用來儲存地理位置資料,MyISAM儲存引擎支援該型別的索引。 - 全文索引
比較類似於搜尋引擎做的事情,查詢的是文字中的關鍵字。
字首索引
索引較長的整個字元列,會使得索引變得佔用空間大、查詢慢,因此可以只使用該字元列的最開始一段字元來作為索引。
假設資料表中存放了某個公司所有員工的資訊,現在要在身份證號這一列上新增一個索引,可能新增一個索引長度為18(身份證號碼的長度),但是其實沒有必要。分析身份證號碼的組成可知,號碼由6位地區碼、8位生日、3位數字順序碼和1位數字校驗碼組成。如果公司人數不多,那麼使用6位的字首索引,如果人數多一點,可以使用14位的字首索引。。。
那麼問題來了,怎麼確定字首索引的合適長度,總不能這樣跟著感覺來把。
現在問題是:怎麼利用字首索引來儘可能達到整列索引(就是索引整個列)的效果,而又能夠佔用較小的空間?
我們可以利用索引的選擇性
假設身份證號碼這一列名稱為person_id,我們可以首先確定有多少個不同的person_id:
SELECT COUNT(*), person_id FROM employee;
然後檢視如果以前6個字元作為索引,效果會如何:
SELECT COUNT(*), LEFT(person_id,6) AS pref FROM employee GROUP BY pref;
然後把6改成其他的值,檢視不同的字首長度會有什麼不同的效果。
如果某個字首長度比較小,並且執行以上SQL語句之後的輸出值中,相應第二列(person_id和pref列)的第一列數值比較接近,那麼這個長度的字首索引是比較合適的。(換句話說,通過該長度的字首索引和對應的整列索引篩選出來的資料數量是差不多的)
一般而言,字首索引長度越長,選擇性就越高,但是索引佔用空間會變大。因此選取多長的字首索引需要自己好好斟酌。
字首索引可以是索引變得更小、更快,但是MySQL無法使用字首索引做ORDER BY和GROUP BY操作,也無法使用字首索引做覆蓋掃描。
多列索引
選擇合適的索引列順序