MS SQL Server每个物理操作的实际CPU成本

时间:2017-03-28 12:08:29

标签: sql-server performance cpu-usage sql-execution-plan

我在Microsoft SQL Server上执行查询的速度很慢。以下是查询和执行计划:https://www.brentozar.com/pastetheplan/?id=BJUrHRwng

查询非常慢:

Table 'Worktable'. Scan count 30, logical reads 184041, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'SiteVersions'. Scan count 1, logical reads 363, physical reads 0, read-ahead reads 351, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table '#BB50937F'. Scan count 1, logical reads 5979, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'AllWebs'. Scan count 11, logical reads 3041, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'AllSites'. Scan count 1, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row(s) affected)

 SQL Server Execution Times:
   CPU time = 715296 ms,  elapsed time = 873728 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

这是在双Intel(R)Xeon(R)CPU E5-2680 0 @ 2.70GHz,2700 Mhz,8 Core(s),16 Logical Processor(s)系统上。查询以max-dop为1执行。

实际执行计划表明特定排序操作具有最大的估计成本,并且没有返回极大行数的操作。

但是,当我检查实际执行计划时,我发现排序操作不太可能导致所有CPU负载。例如,当我在单独的独立查询中执行排序操作时,速度非常快。

我怀疑合并连接是性能杀手:它连接两个平均大的行集(分别为29840和9557行),导致可能存在大量连接的行。它有一个非常非常严格的WHERE子句和一个昂贵的RESIDUAL操作,需要为每个剩余行评估几个函数。但是,我无法支持我对实际数字的怀疑。

因此,我有几个问题,所以我可以证实我的怀疑:

  • 有没有办法从SQL Server获取每个物理操作报告的实际CPU成本?
  • 有没有办法报告执行的RESIDUAL操作的实际数量和/或合并连接操作中WHERE子句后剩余的行数?
  • 有没有办法估算与184041报告的“工作台”逻辑读取相关的CPU成本?
  • 有没有办法找出哪个物理操作使用'工作台'

问候,节拍

2 个答案:

答案 0 :(得分:0)

我不会太担心您看到的CPU成本,它们只是一个指标,可以让您了解CPU从查询中获得的压力。在这种情况下,我认为CPU成本是由查询的复杂性引起的,子查询中的rank()和where子句中的函数。

我会尝试在几个逻辑部分中拆分您的查询,以帮助查询优化器找出最佳计划并使用中间结果改进它的工作:

    select  SiteId
          , WebId
          , VersionId
          , Version
          , rank() over (partition by SiteId, WebId, VersionId order by Id desc) as Rank
    into    #tempSiteVersions
    from    SiteVersions;

    with cteFirstRankingSites as
    (
        select  SV.SiteId
              , S.PlatformVersion
              , SV.Version
              , SSV.ApplicableWebTemplate
              , W.WebTemplate
              , SSV.PreviousTargetVersionNumber
              , SSV.TargetVersionNumber
        from    #tempSiteVersions as SV
                join TVF_Webs_NoLock_ALL() as W on W.SiteId = SV.SiteId
                join Sites as S with (nolock) on W.SiteId = S.Id
                join @SiteSequenceVersions as SSV on SV.VersionId = SSV.Id
        where   SV.Rank = 1
    )
    select distinct
            SiteId
    from    [cteFirstRankingSites] as frs
    where   (
             (
              (dbo.fn_ConvertVersionToNumber(frs.PlatformVersion) < 15000000000000)
              and (dbo.fn_ConvertVersionToNumber(frs.Version) < frs.PreviousTargetVersionNumber)
             )
             or (
                 (dbo.fn_ConvertVersionToNumber(frs.PlatformVersion) >= 15000000000000)
                 and (dbo.fn_ConvertVersionToNumber(frs.Version) < frs.TargetVersionNumber)
                )
            )
            and (
                 frs.ApplicableWebTemplate = 0
                 or frs.ApplicableWebTemplate = frs.WebTemplate
                )

由于我没有可用的实际表格和函数,因此可能存在语法错误,但您明白了。

答案 1 :(得分:0)

  

有没有办法从SQL Server获取每个物理操作报告的实际CPU成本?

您可以使用下面的Set Statistics配置文件,它会单独报告每个逻辑运算符,否则您可以右键单击逻辑运算符以查看成本

选项1:

在上设置统计资料 你的查询

选项2:
右键单击并查看节点属性
enter image description here

选项3:
适用于2016 sp1,您可以使用DMV以下,但您必须在查询前附加set statistics profile

通过这种方式,您可以跟踪实时统计信息和更多信息

select 
session_id,physical_operator_name,
row_count,actual_read_row_count,estimate_row_count,estimated_read_row_count,
rebind_count,
rewind_count,
scan_count,
logical_read_count,
physical_read_count,
logical_read_count
 from
sys.dm_exec_query_profiles
where session_id=55;
  

是否有办法报告执行的RESIDUAL操作的实际数量和/或合并连接操作中WHERE子句后剩余的行数?

这已在SQLServer中实现,但为了显示这一点,您必须使用SSMS 2016并且版本大于SQL2012 sp3,(我在2016年sp1,我可以看到,不确定2014年)。参见下文我机器的截图..

enter image description here

  

有没有办法估算与184041报告的“工作台”逻辑读取相关的CPU成本?

工作台将与操作员相关联,因此跟踪操作员将为您提供操作员的费用

  

有没有办法找出哪个物理操作使用'工作台'

主要是排序操作员使用工作表。在您的情况下,它是具有排序警告的操作员

有关修复查询的建议很少:

1。)我在Partition by query中看到排序运算符的成本为73%,因此我建议使用以下索引来排除排序。此索引仅适用于此查询

create index nci_somename on siteversions
(siteid,webid,versionid,id desc)
include(version)

另外我建议将上面的输出插入到派生表中,如果表很大,那么SQL可以有正确的统计信息

2.)所有网站列显示统计信息警告,尝试更新该表的统计信息或手动创建一个

3.)您的谓词如下所示

dbo.fn_ConvertVersionToNumber(S.PlatformVersion) < 15000000000000)

这些类型的谓词根本不会被攻击。重写它们