MySQL索引之組合索引

1.概念


 對於某些業務情況,當單列索引滿足不了現實的業務,爲了提高搜索效率,就需要考慮運用於組合索引.

 組合索引:即一個索引包含多個列;


2. 添加索引

ALTER TABLE people ADD INDEX `index_name` ( `column1`,`column2`,`column3`);


3.測試

建立基於departID,doctorID,scheduledTime的組合索引,執行計劃如下:



4.最左前綴索引失效問題


之前創建的IDX_MBScheding_Group的組合索引,相當於創建了(departID,doctorCode,scheduledTime)、(departID,doctorCode)、(departID,scheduledTime)這些列組合上的索引.但是因爲"mysql組合索引最左前綴"(Leftmost Prefixing)的結果.則不存在(doctorID,scheduledTime)等這樣的組合索引.


最左前綴索引有效與無效列表:

//The following queries can use the Leftmost Prefixing index:
//where後過濾字段可不按該排序
select ID,ScheduledDate from TB_MB_Scheduling where departID = 309 and doctorCode = '0003' and ScheduledTime = 'SW'
select ID,ScheduledDate from TB_MB_Scheduling where departID = 309 and doctorCode = '0003' 
select ID,ScheduledDate from TB_MB_Scheduling where departID = 309 and ScheduledTime = 'SW'
select ID,ScheduledDate from TB_MB_Scheduling where departID = 309
//The following queries cannot use the Leftmost Prefixing index at all:
select ID,ScheduledDate from TB_MB_Scheduling where doctorCode = '0003' and ScheduledTime = 'SW'
select ID,ScheduledDate from TB_MB_Scheduling where doctorCode = '0003'
select ID,ScheduledDate from TB_MB_Scheduling where ScheduledTime = 'SW'





不存在(doctorID,scheduledTime)等這樣的組合索引:

從執行計劃可以看出最左前綴索引已經失效,直接進行全表掃描

- 那麼問題來了,創建的索引順序與where語句後順序是否需要一致呢?

     在滿足最左前綴索引情況下,查看where語句後字段不同的排序後的執行計劃,發現:創建組合索引時字段的排序與where語句後順序是不需要一致的.


總結:最左前綴是不是失效其實就是取決於你創建索引時,哪個字段排在首位,只要你的搜索條件包含有排在首位的那個字段就能走創建的索引,即滿足最左前綴.

比如:基於(departID,doctorID,scheduledTime)創建的索引IDX_MBScheding_Group,只要where含有過濾字段departID=XXX,無論過濾字段順序先後,都走索引IDX_MBScheding_Group.

- 那麼問題又來了,怎麼才能確定合適的索引列順序呢?


5.選擇合適的索引列順序

正確的順序依賴於使用該索引的查詢,並且同時需要考慮如何更好的滿足排序和分組的需要(本小節只適合B-Tree索引;哈希或者其他類型的索引並不會像B-Tree索引一樣按順序存儲數據)

不需要考慮排序和分組時,將選擇性最高的列放在前面通常時很好的.這時候索引的作用只是用於優化where條件的查找.


以下面查詢爲例

select * from TB_MB_Scheduling where departID = 309 and doctorCode = '0003' and ScheduledTime = 'SW'

是應該創建一個(departID,doctorCode,scheduledTime)還是顛倒一下順序?還是?


5.1 具體查詢法


可以先跑一下來確定在這個表中值的分佈情況,並確定哪個列的選擇性更高.先查看各個where條件的分支對應的數據基數有多大:



所以應該把索引列doctorCode放在前面,因爲對應的條件值doctorCode數量更小.然後根據doctorCode的條件值,查看對應的其他2列的選擇性如何:


(注:查詢結果根據你選定條件的具體值而定)


5.2 經驗法


經驗法則考慮的是全局基數和選擇性.而不是具體的某個查詢.



doctorCode的選擇性更高,所以應該將其作爲第一列.


       


參考來自:

1.<<高性能MySQL>>

2.http://blog.csdn.net/xtdhqdhq/article/details/17582779


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章