1 什么是索引
索引是由一個或者多個列組成的排序的數據結構,通過索引可以高效的找到行的指針,然后根據指針提取行數據,避免低效全表掃描
索引的類型
- B-Tree索引
從索引的根節(jié)點開始進行搜索。根節(jié)點的槽中存放了指向子節(jié)點的指針,儲存引擎根據這些指針向下層查找。通過比較節(jié)點頁的值和要查找的值可以找到合適的指針進入下層子節(jié)點,這些指針實際上定義了子節(jié)點頁中的值的上限和下限。最終儲存引擎要么是找到對應的值,要么該記錄不存在。
可以使用B-Tree索引的查詢類型:
假定有個索引由三個月(first_name, last_name, age)組成
1、全值匹配:和索引中的所有列進行匹配,比如
where first_name='yang' and last_name='zhi' and age=20
2、匹配最左前綴:匹配索引列中的前幾列,比如
where first_name='yang'
3、匹配列前綴:比如以什么開頭
where last_name like 'y%'
4、匹配范圍值:比如時間、數值
where age > 20 and age < 30
5、精確匹配某一列并范圍匹配另一列
where first_name='yang' and last_name like 'zh%'
6、只訪問索引的查詢:即“覆蓋索引”
select age from table where first_name='yang' and last_name='zhi'
B-Tree索引的限制:
1、如果不是按照索引的最左列開始查找,則無法使用索引,比如
where last_name='zhi',從第二列l(wèi)ast_name開始查找,這樣無法使用索引
2、不能跳過索引中的列,比如
where first_name='yang' and age=20,跳過了中間的列“l(fā)ast_name”,這樣也無法使用索引
3、如果查詢中有某個列的范圍查詢,則其右邊的所有列都無法使用索引優(yōu)化查找,比如
where first_name='yang' and last_name like 'z%' and age=20,中間有l(wèi)ike的范圍查詢,所以后面的age無法使用索引優(yōu)化
索引列的順序非常重要!!!
- 哈希索引
只有Memory引擎支持,哈希索引只包含哈希值和行指針,不包括字段值;哈希索引數據不是按照索引值順序儲存的,所以無法用于排序;也不支持部分索引列匹配查找,因為哈希索引使用索引列的全部內容來計算哈希值;哈希索引只支持等值比較;
經驗:可以利用哈希索引思想來優(yōu)化B-Tree對于長字符串值的索引,比如可以把很長的url,取哈希值(CRC32(url))儲存到一個列url_crc,然后查詢,where url='url' and url_crc = CRC32('url'),這樣性能會非常高,為什么要加上url='url'呢?處理哈希沖突
空間數據索引(R-Tree)
比如儲存地理GIS位置,目前支持不完善
全文索引
類似ES,如果對全文搜索要求很高,就直接用ES吧~
2 索引的優(yōu)點
1、大大減少了服務器需要掃描的數據量:如果不用索引則需要全盤掃描;
2、可以幫助服務器避免排序和臨時表:因為索引就是有序的,讀取數據的時候就已經是排序了,否則排序都是需要建立臨時表的;
3、可以將隨機I/O變?yōu)轫樞騃/O:按順序讀取數據非常高效,隨機I/O代價很昂貴;
3 高性能的索引策略
- 獨立的列
查詢的條件必須是獨立的列,如
where age + 20 > 30
where length(first_name) = 10
條件左邊需要計算、函數調用,這樣就不是獨立的列
- 前綴索引和索引選擇性
前綴索引即建立以列的前幾個字符作為索引,比如KEY(city(7))
索引選擇性:索引值占列中所有值的比重,一般來講,比重越高越好,比如唯一索引的索引選擇性就是1;
- 多列索引
重點:在多個列上建立獨立的單列索引大部分情況下并不能提高MySQL的查詢性能!!!
多列索引要按照查詢的需求來建立,如果只是幾個獨立的單列索引,系統(tǒng)雖然會使用“索引合并”來優(yōu)化查詢,但也說明這個索引建的很差勁!
4 選擇合適的索引列順序
索引列的順序非常重要!
通常把選擇性高的列放在前面會更好,但是在多列索引的情況,選擇性的判斷會有點復雜
5 索引的評價:“三星系統(tǒng)”
1、索引講相關的記錄放到一起則獲得一星;
2、如果索引中的數據順序和查找的排列順序一致則獲得二星;
3、如果索引中的列包含了查詢中需要的全部列則獲得“三星”