SQL語句調優 索引上的資料檢索方法

2021-09-09 00:24:31 字數 3280 閱讀 2515

如果一張表上沒有聚集索引,資料將會隨機的順序存放在表裡。以dbo.salesorderdetail_test為例子。它的上面沒有聚集索引,只有乙個在salesorderid上的非聚集索引。所以**的每一行記錄,不會按照任何順序,而是隨意地存放在hash裡。這個時候如果使用者想要找所有單價大於200的銷售詳細記錄,要執行的語句會是:

set

statistics profile on

select

salesorderdetailid , unitprice

from

salesorderdetail_test

where unitprice >

200

由於表在unitprice上沒有索引,所以sql server不得不對這個表從頭到尾掃瞄一遍,把所有unitprice的值大於200的記錄乙個乙個挑出來。

從執行計畫裡可以清楚地看出來sql server 這裡做了乙個表掃瞄(下圖),後面會詳細介紹如何得到和分析執行計畫

如果這個表上有聚集索引,事情會怎麼樣呢?還是剛才那張表做例子,先給它的值是唯一的字段 unitprice上建立乙個聚集索引。這樣所有的資料都會按照聚集索引的順序儲存。

create

clustered

index salesorderdetail_test_cl on dbo.salesorderdetail_test (salesorderdetailid)

可惜的是,查詢條件unitprice上沒有索引,所以sql server還是要把所有記錄都掃瞄一遍。如下圖

與之前不同的是,執行計畫裡的表掃瞄變成了聚集索引掃瞄。因為在有聚集索引的表上,資料是直接存放在索引的最底層的,所以要掃瞄整個**的資料,就是把整個聚集索引掃瞄一遍。在這裡,聚集索引掃瞄就相當於乙個表掃瞄。所要用的時間和資源與表掃瞄沒有什麼差別。並不是說這裡有了」index」這個字樣,就說明執行計畫比表掃瞄的有多大進步。當然反過來講,如果看到」table scan」的字樣,就說明這個**上沒有聚集索引。

現在在 unitprice 上面建乙個非聚集索引,看看情況會有什麼變化

create

nonclustered

index salesorderdetail_test_ncl_price on dbo.salesorderdetail_test (unitprice)

再次查詢

在非聚集索引裡,會為每條記錄儲存乙份非聚集索引索引鍵的值和乙份聚集索引索引鍵的值(在沒有聚集索引的**裡,是rid值)。所以在這裡,每條記錄都會有乙份 salesorderdetailid和unitprice記錄,按照unitprice的順序存放。再查詢,就會看到這次的sql server不是掃瞄整個表,會根據新建的索引直接找到符合的記錄的值。

但是光用unitprice建立在上的索引不能告訴我們其它欄位的值。如果在剛才那個查詢裡再增加幾個字段返回,sql server 就要先在非聚集索引上找到所有unitprice大於200的記錄,然後再根據salesorderdetailid的值找到儲存在聚集索引上的詳細資料。這個過程可以稱為 「bookmark loopup」

在sql server 2005以後,bookmark loopup 的動作用乙個巢狀迴圈來完成。所以在執行計畫裡,可以看到sql servr是先seek了非聚集索引,然後再用clustered index seek 把需要的行找出來。這裡的巢狀迴圈其實就是 bookmark loopup 如下圖。

注:bookmark loopup就是聚集索引

在sql server裡根據資料找尋目標的不同和方法不同。有下面幾種情況。

結構

scan

seek

堆(沒有聚集索引的表)

tablescan

聚集索引

clustered index scan

clustered index seek

非聚集索引

index scan

index seek

如果在執行計畫裡看到這些動作,就應該能夠知道sql server正在對哪種物件在做什麼樣的操作。表掃瞄表明正在處理的表沒有聚集索引,sql server正在掃瞄整張表。聚集索引掃瞄表明sql server正在掃瞄一張有聚集索引的表,但是也會是整表掃瞄。index scan表明sql server正在掃瞄乙個非聚集索引。由於非聚集索引上一般只會有一小部分字段,所以這些雖然也是掃瞄,但是代價會比整表掃瞄要小很多。clustered index seek 和index seek會比scan 說明sql server正在利用索引結果檢索目標資料。如果結果集只佔**總資料量的一小部分,seek 會比scan便宜很多,索引就起到了提高效能的作用。

了解這些是為以後讀懂執行計畫做基礎。水平有限,暫時為這些吧。大家可以多多交流。

MySQL 處理海量資料時的SQL語句調優

在參與實際專案中,當 mysql 表的資料量達到百萬級時,普通的 sql 查詢效率呈直線下降,而且如果 where 中的查詢條件較多時,其查詢速度無法容忍。想想可知,假如我們查詢 的乙個訂單詳情,如果查詢時間高達幾十秒,這麼高的查詢延時,任何使用者都會抓狂。因此如何提高 sql 語句查詢效率,顯得十...

三 SQL資料檢索11 不從實體表中取的資料

有時需要查詢一些不能從任何實體表中能夠取得的資料。如 將數字1作為結果集或者計算字串 abc 的長度。嘗試使用下面的sql來完成類似的功能 select 1 from t employee執行結果集 111 1111 11結果集 現了不止乙個1,因為通過這種方式得到的結果集數量取決於t employ...

管理調優 檢視資料庫中有無多餘的索引SQL

檢視資料庫中有無多餘的索引,即乙個索引的字段為另乙個索引的前幾個字段。如 index1的定義為 test filed1,filed2 index2的定義為 test filed1,filed2,filed3 則認為 index1是多餘的。摘自 ixora column redundant index...