新的基数估计器 (SQL Server 2014) 还很遥远

2024-02-28

我有一个数据仓库数据库,但我在使用 SQL Server 2014 的新基数估计器时遇到问题。

将数据库服务器升级到 SQL Server 2014 后,我发现查询性能存在很大差异。某些查询的执行速度要慢得多(SQL 2012 中为 30 秒,而 SQL 2014 中为 5 分钟)。 在研究执行计划后,我发现 SQL Server 2014 上的基数估计相差很大,而且我找不到原因。

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

一些细节:

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

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

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

我试图将问题缩小到最简单的例子 – 带有 2 个连接的 SELECT:

以下是 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的基数估计器结果错误?


我认为今天这个有趣的问题没有简单的答案。我知道的最佳答案是以下视频:http://channel9.msdn.com/events/TechEd/NorthAmerica/2014/DBI-B331#fbid= http://channel9.msdn.com/events/TechEd/NorthAmerica/2014/DBI-B331#fbid=。它有许多新旧估计器的例子。视频长约 50 多分钟,但值得花时间。

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

基数估计的旧假设:

  1. 均匀性——数据是均匀分布的。
  2. 独立性 – 第 1 列与第 2 列没有关系。
  3. 遏制——当两个属性可能相同时,假定它们相同。
  4. 包容性——应该有一个匹配。

要在 SQL SERVER 2014 中使用 SQL SERVER 2012 基数估计器,请使用以下选项:

  • 选项 (querytraceon 9481) --恢复到 2012 年

新估算器在做什么(基于视频):

  • SQL Server 在索引中使用平均选择性并进行估计 行数乘以键的密度乘以总行数 索引中的行。
  • 新的估计器不能很好地处理锯齿状分布。
  • 估计器之间的大多数差异都基于 WHERE 子句。
  • 新的基数估计器认为表之间存在相关性。
  • 您可以创建过滤统计信息以改进查询。 (http://msdn.microsoft.com/en-us/library/ms188038.aspx http://msdn.microsoft.com/en-us/library/ms188038.aspx )

待办事项/清单:

1. Auto Create / Update Stats
2.  Check database compatibility mode (120/110)
3.  Test using query trace flags
4.  XML showplan

Update基数估计器的新增功能 (SQL Server 2016)

  1. 越准确。
  2. CE 预测您的查询可能返回多少行
  3. SQL Server 2016 查询存储
  4. 跟踪 CE 基数预测的另一个选项是使用名为 query_optimizer_estimate_cardinality 的扩展事件
  5. CE 了解最大值可能高于上次收集统计数据时的值
  6. CE 理解同一个表上的过滤谓词通常是相关的
  7. CE 不再假定来自不同表的过滤谓词之间存在任何相关性

更多细节:

https://learn.microsoft.com/en-us/sql/relational-databases/performance/cardinality-estimation-sql-server https://learn.microsoft.com/en-us/sql/relational-databases/performance/cardinality-estimation-sql-server

https://www.sqlshack.com/query-optimizer-changes-in-sql-server-2016-explained/ https://www.sqlshack.com/query-optimizer-changes-in-sql-server-2016-explained/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

新的基数估计器 (SQL Server 2014) 还很遥远 的相关文章

随机推荐

  • 直到阈值为止的数字列表的总和

    我有一个整数列表 我想要对其进行求和 直到满足阈值 然后能够访问达到阈值的索引 就像是 summing lt function i sum sum list i index i while sum lt thresholdValue sum
  • HTML5 视频 - 设置 video.currentTime 会破坏播放器

    我正在尝试与 Chrome 中的第三方 html5 视频播放器进行交互 我能够因此获得对它的有效引用 document getElementsByTagName video 1 以及readyState是 4 所以一切都很好 我可以成功 并
  • Gradle - 排除配置的依赖关系,但不排除继承配置的依赖关系

    使用 Gradle 1 0 里程碑 8 我的项目使用 slf4j Logback 进行日志记录 因此我想防止 log4j 上的任何传递依赖项污染我的类路径 因此 我添加了全局排除 如下所示 configurations all exclud
  • 定义自定义颜色变量

    我想在我的代码中全局更改一些按钮颜色 我似乎无法找到一种定义颜色变量然后为该变量分配颜色值的方法 我试过这个 颜色 SelectedColor new Color f1 setBackgroundColor Color rgb 0 0 10
  • C# 以编程方式执行 TNSPing

    是否可以以编程方式在 Oracle 数据库上执行 TNSPing 我知道我可能可以调用 TNSPing 程序并解析生成的任何输出 但我正在寻找一种更强大的方法来处理数据库 TNS Ping 看过了平级 http msdn microsoft
  • 为什么 String 的 format(Object...args) 定义为静态方法?

    我想知道为什么Java5 及以上版本提供了使用 String 类中的静态方法的 printf 样式格式化程序 如下所示 public static String format String format Object args 代替 pub
  • 如何在 ASP.Net 应用程序上使用 salting+hashing?

    我正在从头开始构建一个项目 并且我想以正确的方式做事 我在网上读过有关哈希的内容 这基本上就是将密码转换为 64 个字母的繁文缛节 对吗 腌制怎么样 我的问题是 如何使用 C 对字符串进行哈希处理 MSSQL 中的字段声明类型是什么 nva
  • MVC HTML5 电子邮件标签

    我有一个模型 Required ErrorMessage Email required DataType DataType EmailAddress ErrorMessage Please enter valid email address
  • PowerPoint VBA 中的睡眠/等待计时器不是 CPU 密集型的

    我目前正在制作一个 PowerPoint 演示文稿 该演示文稿在计算机上用作某种信息亭或信息屏幕 它从磁盘上的文本文件中读取文本 该文本文件中的文本显示在 PowerPoint 的文本框中 并且每 5 秒刷新一次 这样我们就可以编辑 Pow
  • 从查询引用子表单

    在 MS Access 2010 中 我有一个查询 它在条件中引用了以下内容 Forms frm Add Item Subform ActiveControl Caption 这使我可以在查询中使用按钮的 标题 文本 以下代码位于 Butt
  • 将触摸和手势转发到 UIScrollview 的视图

    我在转发手势和触摸时遇到一些问题 我玩了很多次 但我无法让它按照我想要的方式工作 基本上我想用 2 个手指控制双屏幕上的滚动视图 并将其他所有内容转发到重叠滚动视图后面的 ipad 视图 为了能够控制双屏上的滚动视图 我进行了子类化UISc
  • 如何将包含 7 位毫秒数的日期字符串转换为 Python 中的日期

    当毫秒有 6 位数字时 f 有效 但如果超过 6 位数字 则会抛出错误 我有一个临时解决方案 将第 7 位硬编码为 0 但是有更好的方法吗 目前以下作品 print datetime datetime strptime 2014 11 19
  • ActiveAdmin - 如何在自定义操作中呈现默认模板

    我们在 Rails3 应用程序中使用 ActiveAdmin 作为默认模型 现在我们需要覆盖显示操作 OrderProcess 模型是瞬态 无表 模型 这意味着所有字段都是从其他数据聚合而来的 我们使用一个内部模块 它提供了必要的方法来模拟
  • 如何以缓存友好的方式访问灵活数组的数组?

    I have records具有灵活的阵列成员 typedef struct record unsigned foo signed bar double number record 我有多个records与相同数量的numbers这样我就可
  • SignalR:加载集线器时出错

    Signalr 不加载我的集线器 SignalR Error loading hubs Ensure your hubs reference is correct e g 我正在打电话app MapSignalR in startup co
  • 未捕获的ReferenceError:未定义FileTransfer(使用cordova 2.7.0)

    我想使用FileTransfer从网络服务器下载文件 代码如下 function downloadFile url var fileTransfer new FileTransfer var uri encodeURI url var fi
  • 异步填充DataTable?

    我在 NET Core 2 0 应用程序中有以下功能 public DataTable CallDb string connStr string sql var dt new DataTable var da new SqlDataAdap
  • 以管理员身份运行批处理文件命令错误.exe'未被识别为内部或外部命令

    以管理员身份运行时出错 BackGroundJob exe 不被识别为内部或外部命令 可操作程序或批处理文件 exe和bat文件都在同一个文件夹中 当我运行它而不以管理员身份运行时它会运行 但要安装此 exe 我需要从同一文件夹以管理员身份
  • CQRS 事件溯源:验证用户名唯一性

    我们以一个简单的 账户注册 为例 流程如下 用户访问网站 点击 注册 按钮并填写表格 点击 保存 按钮 MVC 控制器 通过读取 ReadModel 来验证用户名的唯一性 RegisterCommand 再次验证用户名唯一性 这是问题 当然
  • 新的基数估计器 (SQL Server 2014) 还很遥远

    我有一个数据仓库数据库 但我在使用 SQL Server 2014 的新基数估计器时遇到问题 将数据库服务器升级到 SQL Server 2014 后 我发现查询性能存在很大差异 某些查询的执行速度要慢得多 SQL 2012 中为 30 秒