涉及知識:
1.索引的區別2.回表的優化
問題現象:語句非常簡單,在預算-啟用方案時,會進行查詢的調用。當預算方案過多的時候,distinct的執行效率會顯示降低。
select
distinct fromitems ,
ctllevels
from
tb_ctrlscheme
where
ctrlsys = 'erm'
問題分析:
這里的ctrlsys字段基本不具有篩選性。這里我們可以先看一下目前的執行計劃,在ctrlsys字段上存在索引。
從目前的執行計劃可以得知,雖然走了where條件的索引,但是由于不具備選擇性,所以走了index fast full scan。這樣走效率較低,并且還要回表進行查詢。
這里我們需要說明幾點索引的道理:
1.索引的價值在快速定位。索引不記錄空值,B+樹索引的優勢在于矮而胖。也就是可以通過簡單幾層的樹形查找,迅速找到目標數值。
2.索引本身是有序的。
3.不同的索引有不同的功效。比如:
函數索引:where條件中如果存在函數運算,則索引字段無法生效??梢酝ㄟ^建立函數索引的方式來提高速度。
位圖索引:通過建立位圖,通過與或非的預算,一次鎖定多位,來進行匹配。適用于數量多,基數少的場景。如性別字段。
倒排索引:為了減少熱塊的競爭。比如100001 100002 100003,如果正向建立索引,查找較慢。而將數值反轉,則可以快速通過尾號進行篩選。此時非常適合使用倒排索引。
組合索引:將需要的字段進行多列的組合。比如想要取消回表,則可以通過建立組合索引的方式,讓select的字段不再回表查詢。組合索引的列的選擇以及列的順序比較有講究。一般選擇等值條件作為首列,一般需要盡可能的減少索引跳躍掃描。
這里我們通過建立組合位圖索引,來解決distinct帶來的效率問題。
問題解決:
create bitmap index unfromitems on tb_ctrlscheme(fromitems,ctllevels);
復制代碼
這里我們將distinct的兩列都列入位圖索引。
在進行匹配的時候,可以使用到位圖索引的特性,快速定位重復值。將原來需要十幾秒的SQL變為只需要1秒。因此問題得到解決。
同時刪掉了原來where字段上面的索引,避免回表。有的時候,查詢索引+回表的效率要低于全表掃描,因為全表掃描可以一次讀多個塊。
同時我們還需要注意,各種索引失效的場景以及優劣勢。
位圖索引的劣勢在于,一次需要鎖定多個數據行。如果該表經常進行增刪操作的話,索引維護的成本比較大,容易造成鎖等待。所以,要基于場合進行優化。
最終的執行計劃如下: