1. 程式人生 > >index seek和index scan 提高sql 效率

index seek和index scan 提高sql 效率

pil 統計 內置 系統 字符串 recompile 字符串連接 系統內置函數 from

index seek和index scan 提高sql 效率
解釋解釋index seek和index scan:
索引是一顆B樹,
index seek是查找從B樹的根節點開始,一級一級找到目標行。
index scan則是從左到右,把整個B樹遍歷一遍。
假設唯一的目標行位於索引樹最右的葉節點上(假設是非聚集索引,樹深度2,葉節點占用k頁物理存儲)。
index seek引起的IO是4,而index scan引起的IO是K,性能差別巨大。
關於索引,可以仔細讀讀聯機文檔關於物理數據庫體系結構部分
查詢條件中不要包含運算
這些運算包括字符串連接(如: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了。

查詢條件中不要包含同一張表內不同列之間的運算
所謂的“運算”包括加減乘除或通過一些function(如:select * from tb where col1 – col2 = 1997),也包括比較運算(如:select * from tb where col1 > col2)。這種情況下,SQLServer一樣沒辦法估算開銷。不論col1、col2上都有索引還是創建了col1、col2上的覆蓋索引還是創建了col1 include col2的索引。
但是這種查詢有解決辦法,可以在表上多創建一個計算字段,其值設置為你的“運算”結果,再在該字段上創建一個索引,就Ok了。
(結果集/總行數)被稱為選擇性,比值越大,選擇性就越高。
你得到了它,本文的重點就是選擇性。
統計信息,說白了,就是表中某個字段取某個值時有多少行結果集。統計信息可以說是一種選擇性的度量,SQLServer就是根據它來估算不同查詢計劃的優劣。
若表中總行數為1w,采樣行數為1w。provider_no值為21的只有1行,而值為500的行則有4824行。

我們知道,SQLServer會緩存查詢計劃,假如有這麽一個存儲過程:
create proc myproc
(
@pno int
)
as
select * from charge where provider_no = @pno
第一次我們傳進來一個21,OK,它會緩存該存儲過程的執行計劃為nonclustered index seek那個。後來我們又傳進來一個500,完蛋了,服務器發現它有一個myproc的緩存,so,又通過nonclustered index seek執行,接著你的同夥看到你的查詢花費了巨量的IO,於是,你被鄙視了。
這說明了啥?說明如果你的查詢選擇性變動劇烈,你應該告訴SQLServer不要緩存查詢計劃,每次都應該重新評估、編譯。實現方法很簡單,查詢的尾巴上加一個option(recompile)好了。而且SQL2k5還有一個nb的feature,可以每次只重新編譯存儲過程的一部分(當然,你也可以選擇重新編譯整個存儲過程,這取決於你的需求。詳見聯機文檔。)

index seek和index scan 提高sql 效率