技术开发 频道

SQL语句性能调试与分析之执行计划

  分析执行计划

  执行计划是SQL优化器生成的如何处理给定的请求的一个工作计划。它包含这个请求中药用到的操作符。有一些操作可能会执行多次。一些计划分支可能会并行执行。在这个工作计划中,优化器决定获取语句中涉及到的表的顺序,要使用到那些索引,要使用那些查询方法,要使用那些算法等等。事实上,优化器会在多个执行计划中选择出一个最优的,资源耗费最少的。频繁地生成执行计划也会耗费时间,所以SQL Server也会根据数据量的大小估算生成执行计划所需要的阀值时间。生成执行计划的时间不会超过这个估算的阀值时间。还有一个阀值是根据耗费的资源计算得到的。如果一个工作计划的资源耗费低于这个阀值,就认为它是足够好的,优化器就会停止优化使用这个计划。

  图形执行计划

  SSMS允许我们查看一个图形化的执行计划(快捷键Ctrl+L)。注意当查看一个执行计划的时候,查询并没有运行。一些度量值只能在运行完之后才能得到(实际查询得到的行的数目)。

  使用下面的语句来查看执行计划:

  SELECT custid, empid, shipperid, COUNT(*) 
  AS numorders FROM dbo.Orders WHERE orderdate >= '20080201' 
  AND orderdate < '20080301'
  GROUP BY CUBE(custid, empid, shipperid);

  这个语句查询得到所有可能的聚合值,聚合属性是custid,empid,shipperid。如图1


  注意当这个执行计划占用很大的屏幕空间的时候可以点击右下方的按钮“+”不放,然后拖动鼠标可以查看想要查看的区域。

  执行计划是由一些操作组成的树状结构图。数据从子运算流向父运算。这个结构的顺序是从右到左,从上到下。在这个例子中,运算首选从聚集索引开始,然后是后面的操作缠绕运算-Table Spool

  注意每个运算符旁边有一个百分比,这个值表值这个运算在整个执行过程中所占的资源百分比,这个值只是优化器估计的值。SQL语句的优化工作应该放在那些所占的百分比比较大的操作上面。当把鼠标放上去的时候,会有一个换色的提示框。有一个值是Estimated Subtree Cost。最上方,最作坊的运算时整个运算的资源开销。如图2


  注意这些值只是优化器估计出的值,优化器会使用这个值来和其他的估计值作比较进而选择出一个最优的执行计划。

  另外一个比较好的地方时你可以同时生成多个语句的执行计划,进而对他们进行比较。例如下面的语句:

  --1 SELECT custid, orderid, orderdate, empid, filler FROM 
      dbo.Orders AS O1 WHERE orderid = (SELECT TOP (1) O2.orderid FROM 
      dbo.Orders AS O2 WHERE O2.custid = O1.custid 
      
      ORDER BY O2.orderdate 
      DESC, O2.
      orderid DESC); 
  --2 SELECT custid, orderid, orderdate, empid, filler FROM 
      dbo.Orders WHERE orderid IN ( SELECT (SELECT TOP 
      (1) O.orderid FROM dbo.Orders AS O WHERE O.
      custid = C.custid ORDER BY O.orderdate DESC, 
      O.orderid DESC) AS oid FROM dbo.Customers AS C); 
  --3 SELECT A.* FROM dbo.Customers AS C CROSS APPLY(SELECT TOP 
      (1)O.custid, O.orderid, O.orderdate, O.empid, 
       O.filler FROM dbo.Orders AS O WHERE 
       O.custid = C.custid 
       
       ORDER BY O.orderdate DESC, O.orderid DESC) AS A; 
  --4 WITH C AS ( SELECT custid, orderid, orderdate, empid, filler,
      ROW_NUMBER() OVER(PARTITION BY custid ORDER BY 
      orderdate DESC, orderid DESC) AS n FROM dbo.Orders
      ) SELECT custid, orderid, orderdate, empid, 
      
      filler FROM C WHERE n = 1;

  他们的 查询结果是一样的,但是执行计划是不同的。在每个执行计划的开头有一个百分比指示这个语句在所有的语句所占的开销的百分比。在这个例子中我们可以看到第一个语句的比例是37%,第二个语句的比例是19%,第三个是30%,第四个是14%。从这个结果我们可以粗略的认定第四个语句的效率要高一些。

  当把鼠标放在运算符上面的时候会有一个黄色的提示框如图4


0
相关文章