[英]SQL Server Plans : difference between Index Scan / Index Seek
在 SQL Server 執行計划中,索引掃描和索引查找有什么區別
我在 SQL Server 2005 上。
索引掃描是 SQL Server 讀取整個索引以尋找匹配項的地方 - 這花費的時間與索引的大小成正比。
索引查找是 SQL 服務器使用索引的 b 樹結構直接查找匹配記錄的地方(有關如何工作的想法,請參見http://mattfleming.com/node/192 ) - 所用時間僅與匹配記錄的數量。
要遵循的基本規則是掃描不好,搜索是好的。
索引掃描
當 SQL Server 執行掃描時,它將它想要從磁盤讀取的對象加載到內存中,然后從上到下讀取該對象以查找它需要的記錄。
索引搜索
當 SQL Server 執行查找時,它知道數據將在索引中的哪個位置,因此它從磁盤加載索引,直接轉到它需要的索引部分並讀取到它需要的數據結束的位置. 這顯然是比掃描更有效的操作,因為 SQL 已經知道它正在尋找的數據所在的位置。
如何修改執行計划以使用 Seek 而不是 Scan?
當 SQL Server 正在查找您的數據時,可能使 SQL Server 從查找切換到掃描的最大事情之一是您要查找的某些列未包含在您希望它使用的索引中。 大多數情況下,這會讓 SQL Server 回退到執行聚集索引掃描,因為聚集索引包含表中的所有列。 這是我們現在能夠在索引中包含列的最大原因之一(至少在我看來),而無需將這些列添加到索引的索引列中。 通過在索引中包含額外的列,我們增加了索引的大小,但我們允許 SQL Server 讀取索引,而不必返回聚集索引或它自己的表來獲取這些值。
參考
有關 SQL Server 執行計划中每個運算符的詳細信息,請參閱....
索引掃描:
由於掃描觸及表中的每一行,無論其是否合格,成本都與表中的總行數成比例。 因此,如果表很小或者大多數行符合謂詞的條件,則掃描是一種有效的策略。
索引尋求:
由於搜索僅觸及限定行和包含這些限定行的頁面,因此成本與合格行和頁面的數量成比例,而不是與表中的總行數成比例。
索引掃描只是掃描從第一頁到最后一頁的數據頁。 如果表上有索引,並且查詢觸及大量數據,這意味着查詢檢索的數據超過50%或90%,然后優化器只掃描所有數據頁檢索數據行。 如果沒有索引,那么您可能會在執行計划中看到表掃描(索引掃描)。
索引搜索通常是高選擇性查詢的首選。 這意味着查詢只是請求更少的行數,或只是檢索表中行的其他10個(有些文檔說15%)。
通常,查詢優化器嘗試使用索引查找,這意味着優化器已找到一個有用的索引來檢索記錄集。 但是,如果由於表上沒有索引或沒有有用索引而無法執行此操作,則SQL Server必須掃描滿足查詢條件的所有記錄。
掃描和搜索之間的區別?
掃描返回整個表或索引。 搜索基於謂詞有效地從索引的一個或多個范圍返回行。 例如,請考慮以下查詢:
select OrderDate from Orders where OrderKey = 2
掃描
通過掃描,我們讀取orders表中的每一行,評估謂詞“WhereKey = 2”,如果謂詞為真(即,如果行符合條件),則返回該行。 在這種情況下,我們將謂詞稱為“殘差”謂詞。 為了最大限度地提高性能,我們盡可能評估掃描中的殘差謂詞。 但是,如果謂詞太昂貴,我們可以在單獨的過濾器迭代器中對其進行評估。 殘差謂詞出現在帶有WHERE關鍵字的文本showplan中或帶有標記的XML showplan中。
以下是使用掃描的此查詢的文本showplan(為了簡潔而略微編輯):
| -Table Scan(OBJECT:([ORDERS]),WHERE:([ORDERKEY] =(2)))
下圖說明了掃描:
由於掃描觸及表中的每一行,無論其是否合格,因此成本與表中的總行數成比例。 因此,如果表很小或者大多數行符合謂詞的條件,則掃描是一種有效的策略。 但是,如果表很大並且大多數行不符合條件,我們會觸及更多頁面和行,並執行比必要更多的I / O.
尋求
回到這個例子,如果我們在OrderKey上有一個索引,那么搜索可能是一個更好的計划。 通過搜索,我們使用索引直接導航到滿足謂詞的那些行。 在這種情況下,我們將謂詞稱為“搜索”謂詞。 在大多數情況下,我們不需要將搜索謂詞重新評估為殘差謂詞; 索引確保seek只返回符合條件的行。 搜索謂詞出現在帶有SEEK關鍵字的文本showplan中或帶有標記的XML showplan中。
以下是使用搜索的同一查詢的文本showplan:
| -Index Seek(OBJECT:([ORDERS]。[OKEY_IDX]),SEEK:([ORDERKEY] =(2))ORDERED FORWARD)
下圖說明了尋求:
由於搜索僅觸及限定行和包含這些限定行的頁面,因此成本與合格行和頁面的數量成比例,而不是與表中的總行數成比例。 因此,如果我們具有高度選擇性的搜索謂詞,則搜索通常是更有效的策略; 也就是說,如果我們有一個搜索謂詞可以消除表的很大一部分。
關於showplan的說明
在showplan中,我們區分掃描和搜索以及堆上的掃描(沒有索引的對象),聚簇索引和非聚簇索引。 下表顯示了所有有效組合:
https://blogs.msdn.microsoft.com/craigfr/tag/scans-and-seeks/
簡短的回答:
索引掃描:觸摸除某些列之外的所有行。
索引查找:觸摸某些行和某些列。
使用索引掃描,索引中的所有行都會被掃描以找到匹配的行。 這對於小表來說是有效的。 使用索引查找,它只需要接觸實際滿足條件的行,因此通常性能更高
當索引定義無法在單行上找到滿足搜索謂詞時,就會發生索引掃描。 在這種情況下,SQL Server 必須掃描多個頁面才能找到滿足搜索謂詞的行范圍。
在索引查找的情況下,SQL Server 使用索引定義查找與搜索謂詞匹配的單行。
索引搜索更好、更有效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.