這個題目,舉個例子來說
假設有一句select語法如下:
select t2,t3,t4 from testtable where t2=15189 and t3=2
我們如果要針對這句SQL,建立一個適配的index,有下列兩種建法,都可以做到全涵蓋:
(1)create index idx1 on testtable(t2,t3,t4)
(2)create index idx1 on testtable(t2,t3) include(t4)
(當然clustered index也可以做到全涵蓋,它有點類似於(1),此篇僅先探討這兩種index對上述SQL的優劣分析)
在此我想從內部的結構面做個闡述:
首先,只有key columns會被放在根頁面及中繼頁面之中。include的欄位值,只存在於「分葉層頁面」,在根頁面及中繼頁面是不會把include欄位值放進來的,因為include欄位並不用於搜尋。所以include的做法,可以節省根頁面及中繼頁面的數量(因為key欄位變少了)
在分葉層頁面中呢,則不論是keys columns或 include columns都會被存放在分葉層頁面裏。
從分葉層頁面(leaf page)來講,這兩者兩者佔用的空間是一樣的。
從非分葉層頁面(root/intermediate
page)來看,上面的(2)使用include,它的index row會比較短,因此會降低中繼頁面的數量,從這個角度上來講(2)優於(1)。
(1)與(2)的差別在於include的欄位不加入排序(亦即無法當作搜尋欄位),它的好處是,新增資料時,速度會比keys欄位的index要快,因為它可以少一次的排序重組動作。如果是keys欄位,則三個欄位都必需按順序來排,當新增或異動資料時速度較慢。
再畫個圖來說明:
有兩個index
idx1的key只有一個id,其它兩個name,city是include columns
idx2的key包含了id,name,city,沒有include
這時候,如果再新增一筆「10001,Alan、NY」的資料進來,該如何存放
由於idx1,只用id當key,所以它不用考慮name,city的排序,但idx2是用3個欄位當key,所以它需考慮name,city的排序,因為idx2在新增資料的時候,會比較慢。(如果有update到key值,也是一樣需要考慮排序)。因此從這點來看(2)同樣優於(1)。
謝劉老師詳細的說明
回覆刪除想知道如果一個資料表有 n 個欄位,但不同的查詢需要 select 不同的欄位,但條件式都是 where t2=xxx and t3=ooo
回覆刪除那麼若是建立成 include 全部欄位,跟 include 會被 select 的欄位,二者的效能會有什麼差異呢?