有个系统,昨天Support人员发布了相关升级脚本后,今天发现系统中有个功能不能正常使用了,直接报超时了(Timeout expired)的错误。定位到相关相关存储过程后,然后在优化分析的过程中,又遇到了执行计划COST “欺骗”我们的这种情况,其实在我这篇博客”SQL SERVER中用户定义标量函数(scalar user defined function)的性能问题“有提及这个问题,但是很多时候,我们优化SQL的时候,会习惯去查看实际执行计划COST所占的开销比例,从而判断性能开销最大的SQL语句。当然大多数时候,这也是正确的。我们先来看看这个案例吧,如下所示,这个存储过程的部分实际执行计划如下(实际执行计划实在太长,无法全部展现):

我们将实际执行计划保存为sqlplan类型的文件(Execution Plan Files),然后用Plan Explorer展现出来,如下所示,Est Cost% 和 Est CPU  Cost% 显示第一个SQL语句是整个存储过程里面开销消耗最大的SQL语句。然后去测试验证,发现这个SQL不是开销最大的SQL,也就是说执行计划欺骗了我们,实际上,下面Est Cost %为13.3的SQL才是性能开销最大的SQL

从实际执行计划中找到elapsed time最长的SQL,这个SQL才是真正影响性能的SQL语句,然后查看这个SQL语句,发现其查询条件(WHERE)使用了自定义标量函数(因为修改业务逻辑,查询条件添加了自定义函数过滤数据),然而这个从实际执行计划去看也是看不出问题的,因为这个自定义标量函数哪怕调用了几十万次,它的开销代价在实际执行计划中并没有呈现出来。具体原因截取“SQL SERVER中用户定义标量函数(scalar user defined function)的性能问题“中的一段翻译如下:

翻译:

但是需要再次注意,执行计划在欺骗你,首先,它意味着只调用了UDF一次,其实不是这样。其次,从成本(Cost)来看,你可能会认为0%是向下舍入影响,因为单次执行函数的开销如此之小,以至于执行100,000次的成本也很小。但如果你检查执行计划的功能迭代器的属性,你会发现所有的操作代价和子树代价实际的估计为0,这是一个最糟糕的谎言。因为它可能不只是为了欺骗我们,而是SQL SERVER为了欺骗它自己。实际上是查询优化器认为调用函数的成本为0,因此它生成的所有执行计划都是基于调用UDF是免费的。其结果是即使调用标量UDF的代价非常昂贵,查询优化器也不会考虑优化它。

其实又单独总结一下这个问题,是因为人们或多或少受习惯性思维的影响,哪怕我之前多次遇到这种案例,但是在调优过程中,我还是会习惯性按照实际执行计划的COST比例去定位性能开销大的SQL语句,直到我通过验证推翻了这个判断,然后通过elapsed time最长的SQL语句才定位到开销最大的SQL。所以在调优、优化过程中,一定要多方位着手,反复推敲验证,不能被经验主义牵着鼻子走!

SQL Server实际执行计划COST"欺骗"案例的更多相关文章

  1. SQL Server 优化-执行计划

    对于SQL Server的优化来说,优化查询可能是很常见的事情.由于数据库的优化,本身也是一个涉及面比较的广的话题, 因此本文只谈优化查询时如何看懂SQL Server查询计划.毕竟我对SQL Ser ...

  2. 了解Sql Server的执行计划

    前一篇总结了Sql Server Profiler,它主要用来监控数据库,并跟踪生成的sql语句.但是只拿到生成的sql语句没有什么用,我们可以利用这些sql语句,然后结合执行计划来分析sql语句的性 ...

  3. SQL SERVER 2012 执行计划走嵌套循环导致性能问题的案例

    开发人员遇到一个及其诡异的的SQL性能问题,这段完整SQL语句如下所示: declare @UserId             INT declare @PSANo              VAR ...

  4. 程序员眼中的 SQL Server-执行计划教会我如何创建索引?

    先说点废话 以前有 DBA 在身边的时候,从来不曾考虑过数据库性能的问题,但是,当一个应用程序从头到脚都由自己完成,而且数据库面对的是接近百万的数据,看着一个页面加载速度像乌龟一样,自己心里真是有种挫 ...

  5. SQL Server-执行计划教会我如何创建索引

    先说点废话 以前有 DBA 在身边的时候,从来不曾考虑过数据库性能的问题,但是,当一个应用程序从头到脚都由自己完成,而且数据库面对的是接近百万的数据,看着一个页面加载速度像乌龟一样,自己心里真是有种挫 ...

  6. Sql Server中执行计划的缓存机制

    Sql查询过程 当执行一个Sql语句或者存储过程时, Sql Server的大致过程是 1. 对查询语句进行分析,将其生成逻辑单元,并进行基本的语法检查 2. 生成查询树(会将查询语句中所有操作转换为 ...

  7. SQL Server控制执行计划

    为了提高性能,可以使用提示(hints)特性,包含以下三类: 查询提示:(query hints)告知优化器在整个查询过程中都应用某个提示 关联提示:(join hints)告知优化器在查询的特定部分 ...

  8. sql server 根据执行计划查询耗时操作

    with QS as( select cp.objtype as object_type, /*类型*/ db_name(st.dbid) as [database], /*数据库*/ object_ ...

  9. sql server 2008 执行计划

    SSMS允许我们查看一个图形化的执行计划(快捷键Ctrl+L)

随机推荐

  1. Linux启动Redis失败/没有那个文件或目录

    没有那个文件或目录问题,可能是你选择的目录不对. 应切换到Redis目录下启动.

  2. HBase之CF持久化系列(续1)

    这一节本来打算讲解HRegion的初始化过程中一些比较复杂的流程.不过,考虑前面的博文做的铺垫并不够,因此,在这一节,我还是特意来介绍HBase的CF持久化.关于这个话题的整体流程性分析在博文< ...

  3. ubuntu 下安装docker 踩坑记录

    ubuntu 下安装docker 踩坑记录 # Setp : 移除旧版本Docker sudo apt-get remove docker docker-engine docker.io # Step ...

  4. MVC中的下载文件及上传

    前言:最近做的项目中用到了文件下载与上传,一下子想不起来,只能进行百度,为了方便自己做了一个小demo,特此写了这篇小笔记 1.页面方面: 2.控制器方面 namespace MvcUpload.Co ...

  5. SVN客户端安装与使用

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6623148.html  一:SVN客户端下载与安装 下载网址:https://tortoisesvn.net/ ...

  6. HBase学习-HBase原理

    1.系统架构 1.1 图解   从HBase的架构图上可以看出,HBase中的组件包括Client.Zookeeper.HMaster.HRegionServer.HRegion.Store.MemS ...

  7. 自定义微信小程序导航(兼容各种手机)

    详细代码请见github,请点击地址,其中有原生小程序的实现,也有wepy版本的实现 了解小程序默认导航 如上图所示,微信导航分为两部分,第一个部分为statusBarHeight,刘海屏手机(iPh ...

  8. SQL修改表字段,加附属属性

    GO Go EXEC sys.[sp_addextendedproperty] @name = 'MS_Description',@value = '是否填写表单',@level0type = 'SC ...

  9. leetcode — remove-duplicates-from-sorted-array

    import java.util.Arrays; /** * Source : https://oj.leetcode.com/problems/remove-duplicates-from-sort ...

  10. CentOS 7 镜像文件各个版本区别

    CentOS ISO 镜像文件的功能 引导安装 CentOS ISO 镜像文件包含有安装程序,官方称其为 Anaconda,用来引导安装 CentOS 提供 CentOS 的安装文件 镜像文件不一定包 ...