小心SQL SERVER 2014新特性——基数评估引起一些性能问题

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
简介: 原文:小心SQL SERVER 2014新特性——基数评估引起一些性能问题    在前阵子写的一篇博文“SQL SERVER 2014 下IF EXITS 居然引起执行计划变更的案例分享”里介绍了数据库从SQL SERVER 2005升级到 SQL SERVER 2014后,发现一个SQL出现性能问题,当时分析后发现执行计划变了,导致SQL出现了性能问题。
原文: 小心SQL SERVER 2014新特性——基数评估引起一些性能问题

    在前阵子写的一篇博文“SQL SERVER 2014 下IF EXITS 居然引起执行计划变更的案例分享”里介绍了数据库从SQL SERVER 2005升级到 SQL SERVER 2014后,发现一个SQL出现性能问题,当时分析后发现执行计划变了,导致SQL出现了性能问题。但是没有彻底搞清楚为什么出现这种情况。当时看到Actual Number of Rows 与Estimated Number of Rows之间的偏差较大(统计信息是最新的),以为是优化器的Bug造成的。其实罪魁祸首是SQL SERVER 2014新特性——基数评估(Cardinality Estimator)所引起的。IF EXISTS完全成了我这个标题党的替罪羊(罪过罪过)。下面我再就这个问题展开做一次分析。

 

    查看该SQL语句的实际执行计划,在属性里面我们可以看到CardinalityEstimationModelVersion的值为120,120表示这是新的基数评估,70就是老的基数评估

其实当数据库的兼容级别为120的时候,默认使用新的基数评估。也就是说启用了新的基数评估,那么我们现在使用查询跟踪标记9481来关闭新的基数评估,使用老的基数评估。

DBCC TRACEON(9481, 1);
 
GO

启用跟踪标记9481后,这个SQL语句的执行计划变了(可以对比图4),可以看到CardinalityEstimationModelVersion的值也变为了70。SQL语句一秒就执行完了。这个是因为基数评估出现了偏差导致了不合适的JOIN算法。

我们对比下面”图四:旧执行计划“,发现其实还是使用Nested Loops,只是外部循环表与内部循环表变了。   

图四:旧执行计划

那么关于新的基数评估(Cardinality Estimator)特性,你想多了解一些这方面的知识,可以参考官方文档Optimizing Your Query Plans with the SQL Server 2014 Cardinality Estimator。 中文翻译版本可以参考SQL Server 2014新特性——基数评估(白皮书阅读笔记)下面是官方文档关于基数评估出现偏差可能会造成的一些后果:

 

对于基数评估,每个执行计划中的运算符都有评估值输入,这个值决定了优化器使用什么算法的操作符,同时也决定了最终的执行计划。所以如果评估出现偏差,会导致执行计划选择出现偏差,导致无法选出一个高效的执行计划。

评估出现偏差会出现以下结果:

如果评估过小:

1.原本可以使用并行计划更加有效的,现在使用串行计划

2.不合适的join算法

3.不合适的索引选择,和索引访问方法

如果评估过大:

1.原本使用串行计划更加有效,现在使用并行计划

2.不合适的join算法

3.不合适的索引选择,和索引访问方法

4.过多的内存分配

5.内存浪费和没必要的并发

上面这段对应的英文资料如下所示(英语原文作参考,这才是原汁原味的信息):

The individual operator cost models receive the estimates as input. The estimates are a major factor in deciding which physical operator algorithms and plan shapes (such as join orders) are chosen. They also determine the final query plan that executes. Given these critical plan choices, when the cardinality estimation process contains a significantly skewed assumption, this can lead to an inefficient plan choice. This can, in turn, result in degraded performance.

Under estimating rows can lead to memory spills to disk, for example, where not enough memory was requested for sort or hash operations. Under estimating rows can also result in:

  1. The selection of serial plan when parallelism would have been more optimal.
  2. Inappropriate join strategies.
  3. Inefficient index selection and navigation strategies.

Inversely, over estimating rows can lead to:

  1. Selection of a parallel plan when a serial plan might be more optimal.
  2. Inappropriate join strategy selection.
  3. Inefficient index navigation strategies (scan versus seek).
  4. Inflated memory grants.
  5. Wasted memory and unnecessarily throttled concurrency.

Improving the accuracy of row estimates can improve the quality of the query execution plan and, as a result, improve the performance of the query.

 

 

 

  其实关于SQL SERVER 2014这个新的基数评估(Cardinality Estimator)特性,确实造成了不少SQL出现性能问题。我们数据库升级到SQL SERVER 2014后,被这个新特性坑惨了,由于没有选择最优的执行计划,导致一些SQL出现严重的性能问题,也间接导致了SQL之间的阻塞(block)急剧上升。开发人员和我都在救火队员的角色中疲于奔命。最后我不得不采取将数据库的兼容基本从120降为110。从而立马解决了这个问题。另外从我搜索的一些资料看,SQL SERVER 2014这个新的基数评估(Cardinality Estimator)这个新特性确实还有很多不完善的地方。因为也有不少人都发现升级到SQL Server 2014后出现了性能问题。例如:

   MS SQL Server CPU load goes up dramatically when turning on 2014 features by setting compatibility level

      Query is slow in SQL Server 2014, fast in SQL Server 2012

 

参考资料:

http://dba.stackexchange.com/questions/95609/sql-server-performance-is-slow-when-migrated-from-sql-server-2012-to-sql-server

http://www.cnblogs.com/Amaranthus/p/3678647.html

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
目录
相关文章
|
1月前
|
SQL 存储 关系型数据库
如何巧用索引优化SQL语句性能?
本文从索引角度探讨了如何优化MySQL中的SQL语句性能。首先介绍了如何通过查看执行时间和执行计划定位慢SQL,并详细解析了EXPLAIN命令的各个字段含义。接着讲解了索引优化的关键点,包括聚簇索引、索引覆盖、联合索引及最左前缀原则等。最后,通过具体示例展示了索引如何提升查询速度,并提供了三层B+树的存储容量计算方法。通过这些技巧,可以帮助开发者有效提升数据库查询效率。
117 2
|
19天前
|
SQL 存储 缓存
如何优化SQL查询性能?
【10月更文挑战第28天】如何优化SQL查询性能?
71 10
|
20天前
|
SQL 关系型数据库 MySQL
惊呆:where 1=1 可能严重影响性能,差了10多倍,快去排查你的 sql
老架构师尼恩在读者交流群中分享了关于MySQL中“where 1=1”条件的性能影响及其解决方案。该条件在动态SQL中常用,但可能在无真实条件时导致全表扫描,严重影响性能。尼恩建议通过其他条件或SQL子句命中索引,或使用MyBatis的`<where>`标签来避免性能问题。他还提供了详细的执行计划分析和优化建议,帮助大家在面试中展示深厚的技术功底,赢得面试官的青睐。更多内容可参考《尼恩Java面试宝典PDF》。
|
1月前
|
SQL 监控 数据库
慢SQL对数据库写入性能的影响及优化技巧
在数据库管理系统中,慢SQL(即执行缓慢的SQL语句)不仅会影响查询性能,还可能对数据库的写入性能产生显著的不利影响
|
1月前
|
SQL 存储 数据库
SQL学习一:ACID四个特性,CURD基本操作,常用关键字,常用聚合函数,五个约束,综合题
这篇文章是关于SQL基础知识的全面介绍,包括ACID特性、CURD操作、常用关键字、聚合函数、约束以及索引的创建和使用,并通过综合题目来巩固学习。
35 1
|
1月前
|
SQL 关系型数据库 PostgreSQL
遇到SQL 子查询性能很差?其实可以这样优化
遇到SQL 子查询性能很差?其实可以这样优化
88 2
|
1月前
|
SQL Oracle 关系型数据库
Oracle SQL:了解执行计划和性能调优
Oracle SQL:了解执行计划和性能调优
53 1
|
30天前
|
SQL 数据库 开发者
8种SQL编写陷阱:性能杀手还是团队乐趣?
【10月更文挑战第17天】记住,一个好的开发者不仅要知道如何编写代码,还要知道如何编写高效的代码。
35 0
|
1月前
|
SQL 存储 数据库
慢SQL对数据库写入性能的影响及优化技巧
在数据库管理系统中,慢SQL(即执行缓慢的SQL语句)不仅会影响查询性能,还可能对数据库的写入性能产生显著的不利影响
|
1月前
|
SQL 数据处理 数据库
警惕!这八个 SQL 习惯正在拖垮数据库性能
【10月更文挑战第3天】在日常的数据库开发与维护工作中,编写高效、清晰的SQL语句是每位数据工程师的必修课。然而,不当的SQL编写习惯不仅能降低查询效率,还可能给同事的工作带来不必要的困扰。今天,我们就来揭秘八种常见的“专坑同事”SQL写法,助你避免成为那个无意间拖慢整个团队步伐的人。
35 0
下一篇
无影云桌面