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

相关文章
相关标签/搜索