Sql server 为什么我在两台服务器之间得到不同的实际执行计划?

Sql server 为什么我在两台服务器之间得到不同的实际执行计划?,sql-server,tsql,sql-server-2017,Sql Server,Tsql,Sql Server 2017,我有一个在生产和开发环境中运行的SQL Server查询。完全相同的查询 SELECT DISTINCT [Record_Transformation_ACCRUALS], [Record_Transformation_FA:AMORTIZATION], [Record_Transformation_BONUS:AMORTIZATION], [Record_Transformation_CPH:BYLABOUR], [Record_Transfor

我有一个在生产和开发环境中运行的SQL Server查询。完全相同的查询

SELECT DISTINCT 
    [Record_Transformation_ACCRUALS],
    [Record_Transformation_FA:AMORTIZATION],   
    [Record_Transformation_BONUS:AMORTIZATION],
    [Record_Transformation_CPH:BYLABOUR],
    [Record_Transformation_CPH:BYTARGETHOURS],
    [Record_Transformation_OVERHEAD:CULTURE],
    [Record_Transformation_DEDICATED COSTCENTER],
    [Record_Transformation_PUSHDOWN:EXPENSE],
    [Record_Transformation_OVERHEAD:FACILITIES],
    [Record_Transformation_OVERHEAD:GENOME],
    [Record_Transformation_TAXES:MANAGEMENT],
    [Record_Transformation_TAXES:MARKETING],
    [Record_Transformation_OVERHEAD:OFFICETECH],
    [Record_Transformation_EXPENSE:PASSTHROUGH],
    [Record_Transformation_OVERHEAD:PEOPLEPRACTICES],
    [Record_Transformation_OVERHEAD:RECRUITING],
    [Record_Transformation_TAXES:SALES],
    [Record_Transformation_Static Transfer],
    [Record_Label] 
FROM
    Warehouse_20181204 
WHERE 
    Is_Target_Employee = 1 OR Is_Source_Employee = 1
我们比较了这两个表的创建脚本,它们是相同的(除了有问题的表的名称)

我们还验证了它们都使用了聚集列存储索引

在开发过程中,此查询只需不到一秒钟的时间。按prod大约需要一分钟。我们起初认为数据的大小可能是问题所在,但是差异很小(几十万行)

然后,我们检查了这两个项目的实际执行计划。在dev上,实际执行计划为:

在prod上,实际执行计划非常不同,尽管:

我们发现自己很难理解为什么会这样。我们已验证SQL Server的版本相同:

Microsoft SQL Server 2017 (RTM-CU5) (KB4092643) - 14.0.3023.8 (X64)   
Web Edition (64-bit) on Windows Server 2016 Datacenter 10.0 <X64> (Build 14393:) (Hypervisor)
Microsoft SQL Server 2017(RTM-CU5)(KB4092643)-14.0.3023.8(X64)
Windows Server 2016数据中心10.0(版本14393:)上的Web版(64位)(虚拟机监控程序)
我的问题有两个方面:

  • 我们如何确定为什么prod和dev的执行计划如此不同
  • 在给定类似数据集的情况下,我们如何使prod环境运行得与dev一样快
  • 编辑:

    要求提供的其他一些细节:

    • 两台服务器都有8G内存,可用内存都超过1G
    • 两台服务器都有2个处理器
    • 硬件与您得到的完全相同-两个aws实例大小相同
    • 我们已经验证了两个表和集群列存储索引的sql是相同的
    希望这些将有助于当前SQL计划的所有其他详细信息:

    开发sql计划:

    产品sql计划:

    为那些有兴趣深入执行的人添加粘贴计划的链接


    DISTINCT使您的查询成为这方面的简写:

    SELECT
        [Record_Transformation_ACCRUALS],
        [Record_Transformation_FA:AMORTIZATION],   
        [Record_Transformation_BONUS:AMORTIZATION],
        [Record_Transformation_CPH:BYLABOUR],
        [Record_Transformation_CPH:BYTARGETHOURS],
        [Record_Transformation_OVERHEAD:CULTURE],
        [Record_Transformation_DEDICATED COSTCENTER],
        [Record_Transformation_PUSHDOWN:EXPENSE],
        [Record_Transformation_OVERHEAD:FACILITIES],
        [Record_Transformation_OVERHEAD:GENOME],
        [Record_Transformation_TAXES:MANAGEMENT],
        [Record_Transformation_TAXES:MARKETING],
        [Record_Transformation_OVERHEAD:OFFICETECH],
        [Record_Transformation_EXPENSE:PASSTHROUGH],
        [Record_Transformation_OVERHEAD:PEOPLEPRACTICES],
        [Record_Transformation_OVERHEAD:RECRUITING],
        [Record_Transformation_TAXES:SALES],
        [Record_Transformation_Static Transfer],
        [Record_Label] 
    FROM   Warehouse_20181204 
    WHERE  Is_Target_Employee = 1 OR Is_Source_Employee = 1
    GROUP BY 
        [Record_Transformation_ACCRUALS],
        [Record_Transformation_FA:AMORTIZATION],   
        [Record_Transformation_BONUS:AMORTIZATION],
        [Record_Transformation_CPH:BYLABOUR],
        [Record_Transformation_CPH:BYTARGETHOURS],
        [Record_Transformation_OVERHEAD:CULTURE],
        [Record_Transformation_DEDICATED COSTCENTER],
        [Record_Transformation_PUSHDOWN:EXPENSE],
        [Record_Transformation_OVERHEAD:FACILITIES],
        [Record_Transformation_OVERHEAD:GENOME],
        [Record_Transformation_TAXES:MANAGEMENT],
        [Record_Transformation_TAXES:MARKETING],
        [Record_Transformation_OVERHEAD:OFFICETECH],
        [Record_Transformation_EXPENSE:PASSTHROUGH],
        [Record_Transformation_OVERHEAD:PEOPLEPRACTICES],
        [Record_Transformation_OVERHEAD:RECRUITING],
        [Record_Transformation_TAXES:SALES],
        [Record_Transformation_Static Transfer],
        [Record_Label] 
    
    优化器尝试满足这类查询的两种最常见的方法。首先,它过滤您的列存储索引,以查找
    是\u Target\u Employee=1还是\u Source\u Employee=1
    ;这就是你计划中的过滤器显示的内容。接下来,要通过(或区分)处理组,它将:

  • 对行进行排序,然后使用
    流聚合器
    返回一个不同的集合(如产品执行计划所示)
  • 使用散列匹配筛选行并返回一个不同的集合(如开发版本所示)
  • 我怀疑优化器之所以选择不同的计划,是因为基数估计值存在显著差异。显然,开发计划的表现更好。它的性能可能会更好,因为散列匹配计划在这种情况下效率更高,它在Dev中的性能可能会更好,因为您在Dev中获得了并行执行计划,在Prod中获得了串行计划。

    我建议的行动方针是: 使用查询提示在Prod中运行查询-

    OPTION (QUERYTRACEON 8649);
    
    这将迫使优化器运行并行计划。如果没有并行计划,则会出现另一个问题(可能Prod中的MAXDOP设置设置为1)。如果您确实得到了一个并行计划,并且它提高了性能,那么您已经确定了问题(您需要一个并行计划)。如果并行计划不能解决问题,那么您可能需要考虑该表中包含查询中的所有列的非聚集、筛选的CysNoStand索引,然后用

    进行筛选。
    WHERE Is_Target_Employee = 1 OR Is_Source_Employee = 1
    
    你现在正在做一个大扫描,读取大量不需要读取的行

    发回任何问题

    于2018年6月12日更新: 很抱歉更新太晚,出现了很多工作内容

    我仔细研究了一下执行计划,发现了一些有趣的事情。在阅读@Martin_Smith发布的内容之前,我拍摄了以下截图:

    我百分之百同意串行与并行执行计划在这里不是问题,但是,在产品计划的情况下,串行运行会使糟糕的执行计划变得更慢。正如Martin所解释的,问题在于哈希匹配计划是一个更好的计划

    两个计划都从列存储索引(Dev中为5M,Prod中为6M)中检索相似数量的行。在每个计划中,所有行都将被过滤,但在Prod计划中,所有行都将由排序运算符vs使用其哈希聚合再次处理

    不管你投入多少CPU:对630万行进行19列排序会很慢,特别是对于串行计划。在我看来,并行性的最佳用途之一是处理这样的大型排序。这就是说,不应该需要某种类型的。我以前在哪里见过,当优化器可以使用排序(如在Prod计划中)或散列(如在Dev计划中)解决查询时,它将在强制执行并行执行计划时使用散列选择该计划。我怀疑在您的情况下,强制执行并行计划会导致优化器选择使用散列的计划


    最后-我之前忘了提到这一点,不要在Prod中使用
    选项(QUERYTRACEON 8649)
    ;这是无证的。我用它来测试。在prod使用中,串行与并行并不是一个真正的问题,因为您的最大并行度仅为2

    导致查询速度缓慢的原因是内存不足和大量排序溢出(达到8级)

    您的查询返回
    305
    行,但SQL Server在一个计划中估计
    2561980
    ,在另一个计划中估计
    3709060

    对于305行,您需要一个散列聚合,因为它只需要305个不同分组值的内存,而不需要整个600万行的内存以及排序所使用的额外开销

    即使在使用散列聚合的计划中,对输出行数的高估也意味着您将收到一个过量内存授予警告

    查询内存授予检测到“过度授予”,这可能会影响 可靠性。
    CREATE STATISTICS SomeName ON  Warehouse_20181204  (
        [Record_Transformation_ACCRUALS],
        [Record_Transformation_FA:AMORTIZATION],   
        [Record_Transformation_BONUS:AMORTIZATION],
        [Record_Transformation_CPH:BYLABOUR],
        [Record_Transformation_CPH:BYTARGETHOURS],
        [Record_Transformation_OVERHEAD:CULTURE],
        [Record_Transformation_DEDICATED COSTCENTER],
        [Record_Transformation_PUSHDOWN:EXPENSE],
        [Record_Transformation_OVERHEAD:FACILITIES],
        [Record_Transformation_OVERHEAD:GENOME],
        [Record_Transformation_TAXES:MANAGEMENT],
        [Record_Transformation_TAXES:MARKETING],
        [Record_Transformation_OVERHEAD:OFFICETECH],
        [Record_Transformation_EXPENSE:PASSTHROUGH],
        [Record_Transformation_OVERHEAD:PEOPLEPRACTICES],
        [Record_Transformation_OVERHEAD:RECRUITING],
        [Record_Transformation_TAXES:SALES],
        [Record_Transformation_Static Transfer],
        [Record_Label] ) WITH FULLSCAN