高效SQL查詢之索引(I)

2021-05-22 11:07:41 字數 2081 閱讀 2045

1.1      where 條件的列上都得有統計資訊。

沒統計資訊 sqlserver 就無法估算不同查詢計畫開銷優劣,而只能採用最穩妥的 scan (不管是 table scan 還是 clustered index scan )。一般情況下我們不會犯這種錯誤—— where 條件裡不使用非索引列是個常識。索引上的統計資訊是無法刪除的。

1.2      盡量不使用不等於( != )或者 not 邏輯運算子。

這條規則被廣為傳頌,原因據聯機文件和百敬同學的書講,也是 sqlserver 無法評估不同查詢計畫開銷的優劣。但是 sqlserver2k5 聰明了很多,試驗發現儘管用了 != 或者 not ,查詢還是會被優化。如下:

create table tb1

col1 int identity ( 1, 1) primary key ,

col2 int not null,

col3 varchar ( 64) not null

create index ix_tb1_col2 on tb1

col2

create index ix_tb1_col3 on tb1

col3

declare @f int

set @f = 0

while @f < 9999

begin

insert into tb1 ( col2, col3) values ( 1, 'ssdd' )

set @f = @f + 1

end

insert into tb1 ( col2, col3) values ( 0, 'aadddd' )

insert into tb1 ( col2, col3) values ( 2, 'bbddd' )

insert into tb1 ( col2, col3) values ( 3, 'bbaaddddddaa' )

通過上述**,各位可以看到資料分布。 col2 值為 1 的有 9999 條; col2 值為 0 、 2 、 3 的分別有 1 條。

按照本條規則, != 和 not 帶來的應該是個 scan 操作,但實際情況是:

sql2k5 很聰明,它依據統計資訊分析得出來,應該採用 index seek 而不是 index scan 。(稍微解釋解釋 index seek 和 index scan :索引是一顆 b 樹, index seek 是查詢從 b 樹的根節點開始,一級一級找到目標行。 index scan 則是從左到右,把整個 b 樹遍歷一遍。假設唯一的目標行位於索引樹(假設是非聚集索引,樹深度 2 ,葉節點占用 k 頁物理儲存)最右的葉節點上(如上例)。 index seek 引起的 io 是 4 ,而 index scan 引起的 io 是 k ,效能差別巨大。關於索引,可以仔細讀讀聯機文件關於物理資料庫體系結構部分 )。

1.3      查詢條件中不要包含運算

這些運算包括字串連線(如: select * from users where username + 『pig』 = 『 張三 pig』 ),萬用字元在前面的 like 運算(如: select * from tb1 where col4 like 『%aa』 ),使用其他使用者自定義函式、系統內建函式、標量函式等等(如: select * from userlog where datepart(dd, logtime) = 3 )。

sqlserver 在處理以上語句時,一樣沒辦法估算開銷。最終結果當然是 clustered index scan 或者 table scan 了。

1.4      查詢條件中不要包含同一張表內不同列之間的運算

所謂的「運算」包括加減乘除或通過一些 function (如: select * from tb where col1 – col2 = 1997 ),也包括比較運算(如: select * from tb where col1 > col2 )。這種情況下, sqlserver 一樣沒辦法估算開銷。不論 col1 、 col2 上都有索引還是建立了 col1 、 col2 上的覆蓋索引還是建立了 col1 include col2 的索引。

但是這種查詢有解決辦法,可以在表上多建立乙個計算字段,其值設定為你的「運算」結果,再在該字段上建立乙個索引,就 ok 了。

高效SQL查詢之索引(I)

io 至於為什麼,回頭補一篇 我們常說,要建彪悍的索引 要寫高效的 sql 其實最終目的就是在相同結果集情況下,盡可能減少邏輯io。沒統計資訊 sqlserver 就無法估算不同查詢計畫開銷優劣,而只能採用最穩妥的 scan 不管是 table scan 還是clustered index scan...

高效SQL查詢之索引(I)

沒統計資訊 sqlserver 就無法估算不同查詢計畫開銷優劣,而只能採用最穩妥的 scan 不管是 table scan 還是 clustered index scan 一般情況下我們不會犯這種錯誤 where 條件裡不使用非索引列是個常識。索引上的統計資訊是無法刪除的。這條規則被廣為傳頌,原因據...

基礎演算法 查詢 線性索引查詢(I)

前面介紹的幾種查詢的演算法都是基於資料有序的基礎上進行的。但是在實際的應用中,很多資料集可能有驚人的資料量,面對這些海量的資料,要保證記錄全部按照當中的某個關鍵字有序,其時間代價是非常昂貴的,所以這種資料通常都是按先後順序儲存的。那麼如何能夠快速的查詢到需要的資料呢?辦法就是 索引。索引就是把乙個關...