SQL Server內幕之分析計劃

Analyzing planside

分析計劃性能


要真正瞭解查詢計劃並真正可以發現、修復或解決查詢計劃的問題, 須要對組成這些計劃的查詢操做有一個紮實的理解。總的來講, 有太多的操做員能夠在一章中討論它們。此外, 能夠以無數的方式將這些運算符合併到查詢計劃中。所以, 本節側重於瞭解最多見的查詢運算符-查詢執行的最基本的構造塊, 並對 SQL server 如何使用它們構建各類有趣的查詢計劃提供一些瞭解。具體地說, 本節查看掃描並查找、聯接、聚合、聯合、選擇子查詢計劃和並行性。在瞭解這些基本操做和計劃如何工做以後, 可讓你儘量地分解並理解更大、更復雜的查詢計劃。ui


Scans and Seeksspa

掃描和查找server


掃描和查找是 SQL server 用來從表和索引中讀取數據的迭代器。這些迭代器是 SQL server 支持的最基本的。它們幾乎出如今每一個查詢計劃中。瞭解掃描和查找之間的不一樣之處很重要: 掃描處理整個表或一個索引的整個葉級別, 而查找有效地根據謂詞從索引的一個或多個範圍返回行。blog


首先看一下掃描的例子。請考慮如下查詢:索引

SELECT [OrderId] FROM [Orders] WHERE [RequiredDate] = '1998-03-26'it


RequiredDate 列沒有索引。所以, SQL server 必須讀取 Orders 表的每一行。計算每行的 RequiredDate 的謂詞;若是謂詞爲 true (即, 若是行符合資格), 則返回該行。class


爲了最大化性能, SQL server 儘量在掃描迭代器中計算謂詞。可是, 若是謂詞太複雜或太貴(損耗性能), 則 SQL server 可能會在單獨的篩選器迭代程序中對其進行評估。謂詞以 WHERE 關鍵字或 XML 計劃中的標記出如今文本計劃中<Predicate></Predicate>。date


如下是前面查詢的文本計劃:

|--Clustered Index Scan(OBJECT:([Orders].[PK_Orders]),

WHERE:([Orders].[RequiredDate]='1998-03-26'))


圖10-6 以掃描爲例。

blob.png


因爲掃描會觸及表中的每一行是否符合條件, 所以成本與表中的總行數成正比。所以, 若是表較小或許多行符合謂詞的條件, 則掃描是一種有效的策略。可是, 若是表很大, 而且大多數行不符合條件, 則掃描會觸及更多的頁面和行, 並執行更多沒必要要的 i/o


如今來看一個索引查找的示例。假設咱們有一個相似的查詢, 但此次謂詞在 OrderDate 列上有一個索引:


SELECT [OrderId] FROM [Orders] WHERE [OrderDate] = '1998-02-26'


這一次, SQL server 可使用索引直接定位到符合謂詞的行。在這種狀況下, 謂詞稱爲查找謂詞。在大多數狀況下, SQL server 不須要顯式地評估查找謂詞,索引可確保查找操做只返回符合條件的行。


查找謂詞以SEEK關鍵字或 XML 計劃中的標記出如今文本計劃中<SeekPredicates></SeekPredicates>。

如下是本示例的文本計劃:


|--Index Seek(OBJECT:([Orders].[OrderDate]),

SEEK:([Orders].[OrderDate]=CONVERT_IMPLICIT(datetime,[@1],0)) ORDERED FORWARD)


SQL server 經過自動參數化查詢方法將參數 @1 替換爲日期格式。


圖10-7 索引查找舉例。

blob.png


因爲查找僅觸及符合資格的行和包含這些限定行的頁, 所以成本與限定行和頁的數量成正比, 而不是與表中的總行數成比例。所以, 在使用高度選擇性的查找謂詞時, 查找一般是一種更有效的策略, 即, 若是查找謂詞排除表的很大一部分。

SQL server 區分掃描和查找以及堆上的掃描 (沒有彙集索引的表)、對彙集索引的掃描以及對非彙集索引的掃描。

表10-2 全部有效組合在計劃輸出中的顯示。

blob.png

相關文章
相關標籤/搜索