有个系统,昨天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。所以在调优、优化过程中,一定要多方位着手,反复推敲验证,不能被经验主义牵着鼻子走!

转载于:https://www.cnblogs.com/kerrycode/p/9766497.html

SQL Server实际执行计划COST欺骗案例相关推荐

  1. SQL Server查询执行计划–基础

    为什么查询执行对SQL Server性能很重要? (Why is query execution important for SQL Server performance?) SQL Server性能 ...

  2. sql查询初学者指南_面向初学者SQL Server查询执行计划–类型和选项

    sql查询初学者指南 When a DBA is working with the SQL Server, he/she might sometimes say that the execution ...

  3. 了解Sql Server的执行计划

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

  4. sql查询初学者指南_面向初学者SQL Server查询执行计划–聚集索引运算符

    sql查询初学者指南 We have discussed how to created estimated execution plans and actual execution plans in ...

  5. sql查询初学者指南_面向初学者SQL Server查询执行计划–非聚集索引运算符

    sql查询初学者指南 Now that we understand what Clustered Index Scan and Clustered Index Seek are, how they o ...

  6. 面向初学者的 SQL Server 查询执行计划(1)——聚集索引运算符(Clustered Index)

    在本文中,我们将讨论与聚集索引相关的各种执行计划运算符,以及它们的作用.它们何时出现以及它们何时出现. 执行计划中的每一个运算符都会提供一些有关 SQL Server 运行方式的指标. 我们需要理解这 ...

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

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

  8. [转]SQL Server 2000执行计划成本(1/5)

    表扫描 当没有合适的索引时就发生表扫描操作.这可能意味着没有索引存在或者预期有很多行且比扫描整个表开销更少.如果表是一个堆表,执行计划显示表扫描操作:如果表有聚集索引或者所有需要的值都在一个非聚集索引 ...

  9. sql子句的执行顺序_SQL Server查询执行计划– WHERE子句的示例

    sql子句的执行顺序 previous part of this article, we explained how indexes affect SQL Server query execution ...

最新文章

  1. python selenium unittest_python+selenium+unittest单元测试框架
  2. spring的aware学习
  3. Excel的基础操作
  4. linkerd mysql_Linkerd和k8s无法正常工作
  5. sap 客户独立需求作用_SAP 动态安全库存其中动态时间应用
  6. django 运行python manage.py sqlall books 时报错 app has migration
  7. NUC1090 Goldbach's Conjecture【哥德巴赫猜想 】
  8. C语言深入学习系列 - 字节对齐内存管理
  9. STM32H743中的DCMI无法进入行中断和场中断问题
  10. GH4199变形合金
  11. 文本检测综述(2017 ~ 2021 持续更新)
  12. 艺术类职称计算机考试,2017年职称计算机考试Word2003巩固练习题20
  13. 微信小程序时间标签和时间范围的联动
  14. 基于.Net Core Web MVC的图书查询系统——第四章,添加模型并使用EF Core生成基架自动生成控制器和视图
  15. 酷睿i5 1240p什么水平 i5 1240p参数 i51240p是标压还是低压
  16. 爬了3000万QQ用户数据,挖出了花千骨赵丽颖的QQ号
  17. 基于单片机的秒表计时器系统设计(#0400)
  18. Linux Shell脚本编程基础
  19. Microsoft Word 插件开发——Word外接应用程序开发
  20. 合天——SQL注入实验二

热门文章

  1. JavaScript的作用域(1)
  2. sublime后缀_在sublime text中如何设置某种扩展名文件的默认语法
  3. u检验中的查u界值表_延边双壁波纹管pvc-u
  4. Codeforces Round #493 (Div. 2):C. Convert to Ones
  5. 模拟退火(bzoj 3680: 吊打XXX)
  6. np.concatenate 函数的使用
  7. python机器学习库sklearn——决策树
  8. python制作一个桌面小工具
  9. Quartus中Tools->Netlist Viewers->RTL Viewer
  10. mysql常见内置函数