第15/24周 参数预估问题

大家好,欢迎回到性能调优培训在上2个星期,你已经学过了统计信息,它们为什么重要,还有在SQL Server里它们是什么样的。在这期性能调优培训里我想谈下当前参数预估含有的局限性,还有如何应用不同新技术来克服这些局限。

参数预估错误

上个星期你就看到,当执行计划被编译时,SQL Server使用直方图和密度向量来作参数预估。SQL Server这里使用的模型是个静态的,它有很多的缺点和陷阱。在SQL Server 2014里这些情况会改变——下个星期我会详细讲解这些提升。

为了给你参数预估哪里有问题的具体例子,假设有下列2个表:Orders表和Country表。Orders表里的每条记录代表客户下的订单(像数据仓库情景里的事实表),那个表里通过外键约束指向Country表(它就像纬度表)。现在我们对这2个表进行一个来自UK的销售查询:

1 SELECT SalesAmount FROM Country
2 INNER JOIN Orders ON Country.ID = Orders.ID
3 WHERE Name = ‘UK‘

当你查看它的执行计划时,会发现SQL Server在参数预估上有个大问题。

SQL Server估计行数是501,实际上聚集索引查找运算符的实际行数是1000。SQL Server这里使用idx_ID_SalesAmount统计信息对象的密度向量来做出那个预估:密度向量是0.5(在那列我们只有2个不同值),因此估计行数是501(1001 * 0.5)。你可以通过增加过滤统计信息对象来解决这个问题。这会给SQL Server更多关于数据分布本身的信息,也会帮助参数预估。

1 CREATE STATISTICS Country_UK ON Country(ID)
2 WHERE Name = ‘UK‘

当你现在再次看执行计划时,你会看到现在的估计行数和实际行数是一样了。关于这个问题的更多信息可以查看这个文章:使用过滤统计信息解决参数预估错误

相关列(Correlated Columns)

在SQL Server里对于当前的参数预估的另外一个问题出现在查询谓语是彼此相关的。来看下面的SQL查询:

1 SELECT * FROM Products
2 WHERE Company = ‘Microsoft‘
3 AND Product = ‘iPhone‘

当我们常人来看这个查询时,你马上知道会有多少行返回:0!微软公司不可能卖苹果手机滴。当你对SQL Server执行这样的查询时,查询优化器会独立看每个查询谓语:

在第1步里,参数预估对谓语Company = ‘Microsoft‘完成。

在第2步里,查询优化器生成对另外谓语Product = ‘iPhone‘的参数预估。

最后2个预估相乘(multiplied by each other)生成最后的预估。当第1个谓语生成0.3的参数,第2个生成0.4的参数,最后的参数就是0.12(0.3 * 0.4)。查询优化器对每个谓语各自处理,而不考虑彼此关联。

对于这个特定问题,Paul White写了一篇非常有趣的文章,还有你如何影响SQL Server的查询优化器来生成更好性能的执行计划

小结

对于SQL Server里执行计划的准确性和高性能,统计信息和参数预估非常重要。遗憾的是它们的使用率也是有限的,尤其在一些边缘情况。通过这篇文章你看到你如何使用过滤统计信息帮助查询优化器生成更好的参数预估,还有如何处理SQL Server里的相关列问题。

在下星期的性能调优培训里,我们会进一步讨论新的参数预估,即SQL Server 2014的一部分,还有在哪个情形下,新的实现方法会给你更好的执行计划。请继续关注。

时间: 2024-11-05 14:38:00

第15/24周 参数预估问题的相关文章

第11/24周 重编译

今天我想谈下性能调优培训里的重编译(Recompilations ).当你执行一个查询,SQL Server里另一个变动使你执行计划的剩余部分无效,就会发生重编译.在那个情况下SQL Server需要保证你执行计划的准确性,重编译就会被触发.重编译会给你的SQL Server带来额外的CPU开销. 什么是重编译? 首先我想展示下编译和重编译之间的区别.2个星期前,我们讨论了SQL Server里的编译.当查询优化器把提交的查询转化为实际执行计划时,编译就会发生.这就是说编译在查询执行开始前就发生

使用过滤统计信息解决参数预估错误

参数预估是SQL Server里一颗隐藏的宝石.一般而言,参数预估指的是,在查询编译期间,查询优化器尝试找出在执行计划里从各个运算符平均返回的行数.这个估计用来驱动计划本身生成并选择正确的计划运算符——例如像Nested Loop, Merge Join,还是Hash Join的物理连接.当这些估计错误时,查询优化器就会选择错误的计划运算符,相信我——你的查询就会非常非常非常慢! 查询优化器使用称为统计信息对象作为参数预估.每次当你创建一个索引,SQL Server在下面也会创建一个统计对象.这

第13/24周 直方图和密度向量

欢迎回到性能调优培训.今天我想详细谈下统计信息在SQL Server内部是如何呈现的.假设有这样的问题:执行计划里的某个运算符的估计行数是42,但你知道对于这个查询,42不是正确的答案.但是你怎么来解读统计信息来理解这个估计是从哪里来的?我们来谈论下直方图(Histogram)和密度向量(Density Vector). 直方图(Histogram) 首先我们来看下直方图.直方图的用途是用高效.压缩的方式存储列数据分布情况.每次当你在表上创建索引时(聚集/非聚集索引),SQL Server会为你

第24/24周 数据库维护(Database Maintenance)

哇哦,光阴似箭!欢迎回到性能调优培训的最后一期.今天我会详细讲下SQL Server里的数据库维护,尤其是索引维护操作,还有如何进行数据库维护. 索引维护 作为一个DBA,数据库维护是你工作中非常重要的一部分,让数据库获得最佳性能.一个SQL Server数据库就像一辆车:它需要经常的检查来保证运行没有问题,副作用,且拥有最大可能的性能.SQL Server数据库最重要的部分是它的索引及其对应的统计信息对象.SQL Server运行一段时间后会有索引碎片,统计信息必须更新,这样的话查询优化器才可

第10/24周 计划缓存

在这一期的性能调优培训里,我想详细谈下SQL Server里计划缓存及其副作用.在上一周你已经学到,每个提交给SQL Server的逻辑查询会编译成物理执行计划.那个执行计划然后会被缓存,即被称为计划缓存,用作后期的重用.首先我们来看下即席SQL语句(adhoc SQL statements,对应的反义词:prepared SQL statements)的副作用,即带来的性能问题. 即席SQL语句(adhoc SQL statements) 每次当你提交一个即席SQL语句到SQL Server时

15 函数的参数

定义函数的时候,我们把参数的名字和位置确定下来,函数的接口定义就完成了.对于函数的调用者来说,只需要知道如何传递正确的参数,以及函数将返回什么样的值就够了,函数内部的复杂逻辑被封装起来,调用者无需了解. Python的函数定义非常简单,但灵活度却非常大.除了正常定义的必选参数外,还可以使用默认参数.可变参数和关键字参数,使得函数定义出来的接口,不但能处理复杂的参数,还可以简化调用者的代码. 位置参数 我们先写一个计算x2的函数: def power(x): return x * x 对于powe

配置Tomcat-8.5.15 JVM内存参数

配置Tomcat-8.5.15内存参数 apache-tomcat-8.5.15与之前的版本存在些许差异,配置方式有所改变,并且针对JVM一些参数不再支持.故本文档主要简介一下如何在apache-tomcat-8.5.15容器上配置JVM内存参数. 1.       创建环境变量文件 在%TOMCAT_HOME%\bin\目录下创建文件setenv.bat, 文件内容如下所示: SET JAVA_OPTS=-server  -Xms4g  -Xmx4g 或者内容为: SET  "JAVA_OPT

2018.1.15 6周1次课

六周第一次课(1月15日) 9.1 正则介绍_grep上 9.2 grep中 9.3 grep下 在计算机科学中,对"正则表达式" 的定义是:它使用单个字符串来描述或匹配一系列符合某个句法规则的字符串.在很多文本编辑器或其他工具里,正则表达式通常用来检索和替换那些符合某个模式的文本内容.许多程序设计语言也都支持利用正则表达式进行字符串操作.对于系统管理员来讲,正则表达式贯穿在我们的日常运维工作中,无论是查找某个文档,还是查询某个日志文件并分析其容,都会用到正则表达式. 其实正则表达式只

【周末作业】2015.7.15 第二周 css作业及答案

[作业题] 一.问答题 1. CSS选择器以及引入方式哪几种,CSS选择器有哪些以及它们的优先级 2. 行内元素和块级元素的区别,分别举出6个行内元素和块级元素,块级元素的特点是什么 3. 改变元素外边距是什么属性,改变元素内边距是什么属性 4. 如何让一个div在页面中居中 5. 如何隐藏一个div 6. CSS的注释是什么 7. 怎样定义li列表项目符号为实心矩形 8. margin:5px 2px; 表示什么 9. CSS产生浏览器兼容性问题的原因是什么,举出三个处理浏览器兼容性问题的例子