Sql server 新的基数估计器(SQL Server 2014)已经过时了

Sql server 新的基数估计器(SQL Server 2014)已经过时了,sql-server,sql-server-2014,cardinality-estimation,Sql Server,Sql Server 2014,Cardinality Estimation,我有一个数据仓库数据库,我面临SQL Server 2014新基数估计器的问题 将数据库服务器升级到SQL server 2014后,我发现查询性能有很大的不同。有些查询的执行速度要慢得多(SQL 2012为30秒,SQL 2014为5分钟)。 在研究了执行计划之后,我发现SQL Server 2014的基数估计值相差甚远,我找不到原因 以下是SQL 2012与SQL 2014中查询执行计划(左上角运算符)的示例: | Est.rows - SQL2012 | Est.ro

我有一个数据仓库数据库,我面临SQL Server 2014新基数估计器的问题

将数据库服务器升级到SQL server 2014后,我发现查询性能有很大的不同。有些查询的执行速度要慢得多(SQL 2012为30秒,SQL 2014为5分钟)。 在研究了执行计划之后,我发现SQL Server 2014的基数估计值相差甚远,我找不到原因

以下是SQL 2012与SQL 2014中查询执行计划(左上角运算符)的示例:

           | Est.rows - SQL2012 | Est.rows - SQL2014
Operator 1 |               7653 |               7653
Operator 2 |               7653 |              10000

一些细节:

  • 我的查询是典型的数据仓库事实表加载查询。我查询一个事务表并连接许多(15-20)维度表(总是有0或1条记录从维度表连接)

  • 我已经更新了所有表的统计信息(使用FULLSCAN),以确保统计信息是最新的

  • 维度表的业务键被索引(唯一的非聚集索引)。在我看来,由于该索引的唯一性,旧的基数估计器(SQL 2012)正确地假设最多有1条记录加入(估计的记录数在执行计划中不会改变)

我试图将问题缩小到最简单的示例–选择2个连接:

下面是SQL 2012与SQL 2014中运算符1和运算符2的基数估计:

           | Est.rows - SQL2012 | Est.rows - SQL2014
Operator 1 |               7653 |               7653
Operator 2 |               7653 |              10000
如您所见,SQL Server 2014与估计值的偏差超过30%(10000对7653)。因为我有cca。15-20个连接在一个典型的查询中,最终的估计值相差很远


我可以将数据库置于较低的兼容模式(110)下,然后工作正常(与SQL Server 2012上的情况相同),但我真的想知道这种行为的原因是什么。为什么SQL Server 2014的基数估计器的结果是错误的?

我认为今天这个有趣的问题没有简单的答案。我知道的最佳答案是以下视频:。它有许多新的和旧的估计量的例子。这段视频大约有50多分钟长,但值得一看

与此问题相关的视频摘要:

基数估计的旧假设:

  • 一致性–数据均匀分布
  • 独立性–第1列与第2列无关
  • 包容–当两个属性可能相同时,假定它们相同
  • 包含–应该有一个匹配项
  • 要在SQL SERVER 2014中使用SQL SERVER 2012基数估计器,请使用以下选项:

    • 选项(querytraceon 9481)——恢复到2012年
    新估计器在做什么(基于视频):

    • SQL Server在索引和估计中使用平均选择性 行数乘以键的密度与 索引中的行
    • 新的估计器对锯齿分布不太适用
    • 估计值之间的大部分差异都基于WHERE子句
    • 新的基数估计器认为表之间存在相关性
    • 您可以创建筛选的统计信息以改进查询。()
    待办事项/检查表:

    1. Auto Create / Update Stats
    2.  Check database compatibility mode (120/110)
    3.  Test using query trace flags
    4.  XML showplan
    
    更新 基数估计器的新功能(SQL Server 2016)

  • 越准确
  • CE预测查询可能返回的行数
  • SQL Server 2016查询存储
  • 跟踪CE基数预测的另一个选项是使用名为query\u optimizer\u estimate\u cardinality的扩展事件
  • CE了解最大值可能高于上次收集统计数据时的值
  • CE知道同一个表上的过滤谓词通常是相关的
  • CE不再假设来自不同表的筛选谓词之间存在任何关联
  • 更多详情:


    我想知道您是否遇到了关于多列选择性估计的问题:

    似乎新的CE仍有一些怪癖,请尝试使用TF 4137,看看是否有帮助


    最后,请确保您使用的是最新的CU,并且正在使用TF 4199运行,以全面启用所有查询优化器修复程序,如有可能,请首先在非生产环境中测试这一点,并在全局启用设置时注意其他查询中的回归这并不是对该问题的直接回答,但它可能会帮助那些面临与基数估计器(CE)更改相关的SCCM(又称ConfigMgr)数据库的类似性能问题。由于SQL Server 2014和SQL Server 2016中新的基数估计器(CE)更改,SQL查询可能会超时,或者ConfigMgr控制台可能运行缓慢。Microsoft针对此问题提供了一个解决方案,建议应用适当的SQL基数估计器(CE)兼容性级别,如下表所示:

    SQL Server version    Supported compatibility       Recommended compatibility   
                          level values                  level for ConfigMgr
    
    SQL Server 2016       130, 120, 110, 100            130 
    
    SQL Server 2014       120, 110, 100                 110
    

    希望这有帮助

    这可能与新CE中不同设计的谓词的独立性/相关性有关。不知道它到底是怎么工作的。您可以在这里阅读更多内容:关于2014年新的基数估计器以及它们是如何得出查询计划值的一本好书:同意,这看起来像是一个新的CE稍微高估了(它往往会高估)的案例。按照Joe的帖子中的步骤进行调试将是一个很好的第一步。此外,当属性/谓词之间没有相关性时,遗留CE将更好地工作,这里似乎也是这样。新的指数退避算法将倾向于高于传统CE。