在前阵子写的一篇博文“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.

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

其实关于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 SERVER 2014新特性——基数评估引起一些性能问题的更多相关文章

  1. SQL Server 2014新特性——基数评估(白皮书阅读笔记)

    基数评估 目录 基数评估 说明 基数评估准确的重要性 模型假设 启用新的基数评估 验证基数评估的版本 在迁移到新的基数评估前要测试 校验基数评估 偏差问题 需要手动处理的变化 避免因为新的CE造成性能 ...

  2. SQL Server 2014 新特性——内存数据库

    SQL Server 2014 新特性——内存数据库 目录 SQL Server 2014 新特性——内存数据库 简介: 设计目的和原因: 专业名词 In-Memory OLTP不同之处 内存优化表 ...

  3. 谈谈我的微软特约稿:《SQL Server 2014 新特性:IO资源调控》

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 撰写经历(Experience) 特约稿正文(Content-body) 第一部分:生活中资源 ...

  4. SQL Server 2014新特性——Buffer Pool扩展

    Buffer Pool扩展 Buffer Pool扩展是buffer pool 和非易失的SSD硬盘做连接.以SSD硬盘的特点来提高随机读性能. 缓冲池扩展优点 SQL Server读以随机读为主,S ...

  5. SQL Server 2014 新特性:IO资源调控

    谈谈我的微软特约稿:<SQL Server 2014 新特性:IO资源调控> 2014-07-01 10:19 by 听风吹雨, 570 阅读, 16 评论, 收藏, 收藏 一.本文所涉及 ...

  6. SQL Server 2014新特性:五个关键点带你了解Excel下的Data Explorer

    SQL Server 2014新特性:五个关键点带你了解Excel下的Data Explorer Data Explorer是即将发布的SQL Server 2014里的一个新特性,借助这个特性讲使企 ...

  7. SQL Server 2014 新特性——内存数据库(转载)

    目录 SQL Server 2014 新特性——内存数据库 简介: 设计目的和原因: 专业名词 In-Memory OLTP不同之处 内存优化表 内存优化表的索引 并发能力的提升 和竞争对手相比几点 ...

  8. [SQL Server 2014] SQL Server 2014新特性探秘

    SQL Server 2014新特性探秘(1)-内存数据库   简介 SQL Server 2014提供了众多激动人心的新功能,但其中我想最让人期待的特性之一就要算内存数据库了.去年我再西雅图参加SQ ...

  9. SQL Server 2014新特性:其他

    AlwaysOn 增强功能 SQL Server 2014 包含针对 AlwaysOn 故障转移群集实例和 AlwaysOn 可用性组的以下增强功能: “添加 Azure 副本向导”简化了用于 Alw ...

随机推荐

  1. 【Java心得总结三】Java泛型上——初识泛型

    一.函数参数与泛型比较 泛型(generics),从字面的意思理解就是泛化的类型,即参数化类型.泛型的作用是什么,这里与函数参数做一个比较: 无参数的函数: public int[] newIntAr ...

  2. 解决CHROME中画布中无法显示图片的方法

    最终效果图如下 我按照W3SCHOOL里面的方法,代码如下 <!DOCTYPE html> <html> <body> <script type=" ...

  3. 设置 LongListSelector 只有在项多的时候才分组

    Windows Phone 中的控件LongListSelector是一个很好的分组聚类控件,当列表中数据特别多的时候,LongListSelector就像字典中的目录,让我们很快定位到要找的数据. ...

  4. 淘宝购物车页面 PC端和移动端实战

    最近花了半个月的时间,做了一个淘宝购物车页面的Demo.当然,为了能够更加深入的学习,不仅仅有PC端的固定宽度的布局,还实现了移动端在Media Query为768px以下(也就是实现了ipad,ip ...

  5. Vagrant入门

    简单地说,Vagrant让我们可以通过代码的方式快速地.可重复地创建针对不同虚拟环境的虚拟机,包括Virtualbox.AWS.Docker等.它使得我们可以一次性地.自动创建多个环境相同的虚拟机,对 ...

  6. 实用的60个CSS代码片段

    1.垂直对齐 如果你用CSS,则你会有困惑:我该怎么垂直对齐容器中的元素?现在,利用CSS3的Transform,可以很优雅的解决这个困惑: .verticalcenter{ position: re ...

  7. 用户反馈:对 Rafy 开发框架的一些个人建议

      这篇文章是去年 Rafy 框架发布后,许胜平先生为我提出的一些建议.他从用户群体分析.社区.商业模式.技术支持等方面对框架发展提出了建议,我觉得写得非常不错.此文不仅适用于 Rafy 框架,所以不 ...

  8. Composer根据Name显示与隐藏

    //主要设置 模型的显示与隐藏 private void TransmissionByData_AxSendSelectionChange(string domName, bool isVisible ...

  9. eclipse自动补全的设置(自动提示)

      如果你用过Visual Studio的自动补全功能后,再来用eclipse的自动补全功能,相信大家会有些许失望. 但是eclipse其实是非常强大的,eclipse的自动补全没有VS那么好是因为e ...

  10. Java Web 学习路线

    实际上,如果时间安排合理的话,大概需要六个月左右,有些基础好,自学能力强的朋友,甚至在四个月左右就开始找工作了.大三的时候,我萌生了放弃本专业的念头,断断续续学 Java Web 累计一年半左右,总算 ...