查询开销
尽管查询的执行计划提供了详细的处理策略的单独步骤涉及的估计相对开销,但是它没有提供查询实际的CPU使用、磁盘读写或持续时间等开销。
还有其他比运行Profiler更直接手机性能数据的方法
一、客户统计
客户统计将计算机作为服务器的一个客户端,从这个角度出发去捕捉执行信息。这意味着任何记录事件包括通过网络传送数据的时间,而不仅仅是SQL Server本身所花费的时间。
要使用客户统计,只需要单击=》查询=》包含客户统计。
现在,每当运行一个查询,就会收集一个限定的数据集,包括执行事件,影响的行数、到服务器的往返次数等。进一步,查询的每次执行在客户统计选项卡上被分别显示,有一列将多次的执行进行累加并显示所收集数据的平均值。该统计也以箭头方式显示一次运行和下次运行之间事件或计数是否改变。
执行查询语句,显示的客户端信息如下:
虽然捕捉客户统计可能收集数据的有用手段,但这是个有限的数据集,没有办法显示一次执行与另一次的差别。甚至可能运行完全不同的一个查询,它的数据可能与其他的混合在一起,从而使平均值失去意义。如果需要这么做可以重置客户统计=》查询=》重置客户端统计实现。
二、执行时间
Duration和CPU都代表着查询的时间因素。要获得关于解析、编译和执行查询的总时间详细信息,可以通过SET STATISTICS TIME实现:
执行时间CPU 时间 = 125毫秒表示Profiler工具和服务器跟踪选项所提供的CPU值。相似地对应的占用时间 = 1065毫秒表示其他机制提供的Duration值。
分析和编译时间意味着优化器重用这个查询现有的执行计划,因此不必花费任何时间来再次解析和编译时间。如果查询第一次执行,那么优化器必须首先解析查询语法,然后编译它以生成执行计划。这个可以调用DBCC FREEPROCCACHE清楚缓存,然后重新运行查询:
不应该在生产系统上运行DBCC FREEPROCCACHE,除非准备胡斐无谓的开销重新编译系统上的每个查询,某种程度上,这个系统重启的开销相同。
三、统计IO
为了减少读操作总数,发现查询中访问的所有表以及对应的读操作数量是有用的。
要获得执行查询所化花费的IO可以通过操作GUI得到:
查询=》查询选项=》设置STATISTICS IO:
当然也可以通过编程的方式开启:
在解读STATISTICS IO输出时,多半会参考逻辑读操作数量,有时候也会参考扫描计数。但即使每个扫描执行很少的逻辑读,STATISTICS IO所提供的逻辑读总数仍然可能会很高。如果每个扫描的逻辑读数量对于特定的表很小,那么可能无法进一步地改进该表的索引机制。物理读操作和预读数量在数据无法在内存中找到时不为0,但是一旦数据填写到内存,物理读和预读将趋近于0。
知道查询使用的所有表及其对应的读操作数量还有另一个好处。SQL Server机器上运行的重要服务和后台应用通常会影响所观测的查询处理时间,Duration和CPU值在表结构或数据没有变化的情况下重新执行相同查询,结果常常有很大的波动。
在优化各步骤期间,需要一个没有被动的开销数字作为参考。读操作数量在固定的表结构和数据下的查询多次执行之间不会有变化。例如,如果执行SELECT语句10次,可能得到10个不同的Duration和CPU数值,但Reads每次都保持一致。
下面还给出一些常用的计数及清除缓存的方法:
操作 | 说明 |
DBCC DROPCLEANBUFFERS | 清空数据缓存 |
DBCC FREEPROCCACHE | 清空编译缓存 |
其他统计操作说明:
选项 | 说明 |
SET NOCOUNT | 当 SET NOCOUNT 为 ON 时,不返回计数(表示受 Transact-SQL 语句影响的行数)。当 SET NOCOUNT 为 OFF 时,返回计数。 |
SET ARITHABORT | 在查询执行过程中发生溢出或被零除错误时终止查询。 |
SET NOEXEC | 编译但不执行语句 |
SET SHOWPLAN_TEXT | 不执行 Transact-SQL 语句。但由 SQL Server 返回有关如何执行语句的详细信息。 |
SET PARSEONLY | 解析但不编译或执行语句 |
SET STATISTICS TIME | 统计执行语句所消耗时间 |
SET STATISTICS IO | 统计执行语句所消耗IO |
SET CONCAT_NULL_YIELDS_NULL | 控制是将串联结果视为 Null 还是空字符串值。ON:SELECT 'abc' + NULL; 返回NULL;OFF:SELECT 'abc' + NULL; 返回abc |
SET TRANSACTION ISOLATION LEVEL | 控制到 SQL Server 的连接发出的 Transact-SQL 语句的锁定行为和行版本控制行为。 |
SET DEADLOCK_PRIORITY | 指定当前会话与其他会话发生死锁时继续处理的相对重要性。 |
SET LOCK TIMEOUT | 指定语句等待锁释放的毫秒数。 |
SET QUERY_GOVERNOR_COST_LIMIT | 数值或整数值,用于指定可以运行查询的最长时间。查询调控器不允许执行估计开销超过该值的任何查询。如果指定此选项为 0(默认),将关闭查询调控器,并且允许所有查询无限期运行。 |
更多的设置,可以查看MSDN:http://technet.microsoft.com/zh-cn/library/ms186736(v=sql.90).aspx