SQL Server 2014新特性——基数评估(白皮书阅读笔记)
基数评估
目录
说明
查询优化器的目的是为了找出有效的执行计划,根据cost运算,取出cost最小的计划,作为执行计划。其中影响cost最重要的一项就是基数评估(估计行数)。SQL Server 2014对基数评估做了修改。
基数评估准确的重要性
基数评估提供以下信息:
1.响应行数评估(the distribution of data)
2.不同值个数评估(distinct value count)
3.重复值个数,作为上一级基数评估(duplicate count as input for parent operator estimation calculations)
基数评估是通过计算统计信息的出来的结果,而统计信息通过优化器创建或者通过索引创建。
统计信息分为:头,密度向量,直方图。
当统计信息存在的时候基数评估器使用密度向量和直方图来计算评估。
基数评估主要回答以下几个问题:
1.一个或多个谓词或过滤几行
2.2个表之间的连接谓词会过滤几行
3.预计一个指定列集合中有多少不同值(distinct value)
Sql server中有2种谓词:1.过滤谓词,2.连接谓词
基数评估(CE):试图回答where,join,having这些谓词的选择性。也试图回答group,distinct的不同值(distinct value)。
CE的计算从图形执行计划中是从右到左的,下一级的评估作为上一级计算评估的输入。

每个执行计划中的运算符都有评估值输入,这个值决定了优化器使用什么算法的操作符,同时也决定了最终的执行计划。所以如果评估出现偏差,会导致执行计划选择出现偏差,导致无法选出一个高效的执行计划。
评估出现偏差会出现以下结果:
如果评估过小:
1.原本可以使用并行计划更加有效的,现在使用串行计划
2.不合适的join算法
3.不合适的索引选择,和索引访问方法
如果评估过大:
1.原本使用串行计划更加有效,现在使用并行计划
2.不可合适的join算法
3.不合适的索引选择,和索引访问方法
4.过多的内存分配
5.内存浪费和没必要的并发
模型假设
内核有以下假设:
Independence:假设,在没有额外的相关信息之外,数据在不同的列是没有关联的
Uniformity:在统计信息的直方图的step,数据分布式均匀分布在step上的。
Containment: 2个表连接,那么高密度的一定被低密度的包含。
Inclusion:如果对一列对常数过滤,那么认为这个常数数据一定存在在这个列中。
启用新的基数评估
当数据库的兼容级别为120的时候,就是启用了新的基数评估,默认使用新的基数评估。
但是可以通过查询跟踪标记来指定:
2312:在兼容级别低于120的时候使用新的基数评估
9481:在兼容级别在120下,使用老的基数评估
验证基数评估的版本
可以从图形执行计划或者XML执行计划中找到CardinalityEstimationModelVersion,如果为120就是新的基数评估,70就是老的基数评估。


在迁移到新的基数评估前要测试
新的基数评估虽然总体提示了性能,但是对个别查询来说,会被影响,性能变差,所以要测试。
1.在类似生产环境下,测试大多数的负荷
2.可以先迁移到sql server 2014,但是使用不运行在120兼容级别
3.也可以到120兼容级别,但是在全局范围开9481跟踪标记
4.新建数据库推荐使用默认会使用120兼容级别。
校验基数评估
没有什么特别的就是通过实际值和评估值对个对比。
偏差问题
评估值偏差,是存在的,那么多少算是偏差太大了?其实没有一个固定的值,主要是看以下2点:
1.偏差是不是造成了资源过度使用
2.偏差是不是造成了特定查询的性能问题
如果任意一个出现问题的话,那么就能认为偏差太大了。
需要手动处理的变化
只有评估值变化的情况下,看性能是否下降超过预期,如果超过要进行手动干预。
如果评估值和老CE一样,并且计划没有什么变化,就不需要处理。
避免因为新的CE造成性能下降
1.能够从新基数评估得到性能优化的查询,就使用新基数评估,其他的进行重新调整。
2.有好处的查询使用新的基数评估,其他的使用跟踪标记9481
3.使用老的基数评估,特定的查询可以指定跟踪标记2312
4.直接调试有问题的sql
5.使用老的基数评估
SQL Server 2014中的修改
增加多个谓词的相关性的假设
在没有多列统计信息的情况下,SQL Server优化器会认为谓词之间是不相关的。
老的基数评估:各个谓词的选择度相乘
新的基数评估:选择度从低到高排序,然后使用以下公式:
修改超出统计信息范围的评估
如果超出统计信息范围,那么老的基数评估就认为不存在,评估行数为1。
新的基数评估会用,密度*总行数来当评估。
Join评估算法修改
简单Join
老的基数评估是以线性增长的方式一步一步对齐2个直方图。(根本不知道是怎么玩的)
新的基数评估,使用相对简单的join评估算法,只是用直方图的最大最小边界来对齐。(文章并没有给出详细的算法很坑爹)。
新的基数评估是用这种原则,很容易发现评估值不够准确。
多Join条件
多个join条件,对于老的基数评估来说,是独立的谓词,是用选择度相乘的方法来组合。
新的基数评估,是用2个不同值个数(distinct value count)中较小的一个,然后乘以2边的平均频率。(搞不懂)
Join带相等和不相等的谓词
老的基数评估,是独立的谓词,是用选择度相乘的方法来组合。
新的基数评估,认为大表小标多对1的关系。即大表中的一行,必定存在于表的一样与之对应。这个算法把大表的评估作为评估。(这个简单)
Join包含(Containment)假设的修改
如果是等值连接,那么就会假设这个列表2边都是存在的。如果存在join表上有非join谓词,老的基数评估那么会认为一些级别的相关,这种相关叫做简单包含(Simple Containment)。
老的基数评估的JOIN评估,假设在使用join谓词之前,任意存在的谓词会缩小直方图,而谓词之间是不相关的。老CE用这样的评估方式会让评估值偏大。
USE [AdventureWorks2012];
GO
SELECT [od].[SalesOrderID], [od].[SalesOrderDetailID]
FROM Sales.[SalesOrderDetail] AS [od]
INNER JOIN Production.[Product] AS [p]
ON [od].[ProductID] = [p].[ProductID]
WHERE [p].[Color] = 'Red' AND
[od].[ModifiedDate] = '2008-06-29 00:00:00.000'
OPTION (QUERYTRACEON 9481); -- CardinalityEstimationModelVersion 70

新的基数评估是使用基本包含(Base Containment),新的基数评估,是直接从基表上面获取选择度,而不是经过谓词过滤之后。

不同值计数评估的变化
对于新的基数评估和老的相比在多对多连接中,不同值计数评估相差很小。如果join条件会放大基数,老的基数评估可能会不准确。
新的基数评估根据join谓词和非join谓词选择不同值。新的基数评估使用环境基数(ambient cardinality),环境基数是group by或者distinct列的最小不同值集合(The new CE uses “ambient cardinality”, which is the cardinality of the smallest set of joins that contains the GROUP BY or DISTINCT columns.)。
诊断输出
使用新的xevent,query_optimizer_estimate_cardinality来输出
CREATE EVENT SESSION [CardinalityEstimate] ON SERVER
ADD EVENT sqlserver.query_optimizer_estimate_cardinality
ADD TARGET package0.event_file( SET filename = N'S:\CE\CE_Data.xel' ,
max_rollover_files =( 2 ) )
WITH ( MAX_MEMORY = 4096 KB ,
EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS ,
MAX_DISPATCH_LATENCY = 30 SECONDS ,
STARTUP_STATE = OFF );
GO
-- Start the session
ALTER EVENT SESSION [CardinalityEstimate] ON SERVER STATE=START;
--
-- Your workload to be analyzed executed here (or in another session)
--
-- Stop the session after the workload is executed
ALTER EVENT SESSION [CardinalityEstimate] ON SERVER STATE=STOP;
也可以使用A first look at the query_optimizer_estimate_cardinality XE event中的方法。
新基数评估的调优方法
修改数据库兼容级别
如果新的CE出现性能问题,可以通过修改兼容级别回到以前的CE版本。
使用跟踪标记
可以使用QUERYTRACEON来使用查询级别选项,这个跟踪标记会影响一个语句的CE级别。
基础调优方法
统计信息丢失
统计信息丢失,但是没有及时创建,应该查看是否启用了统计信息自动创建选项。
统计信息过期
统计信息可能太老,导致查询性能问题,考虑是否要手动跟新统计信息。
统计信息采样率
表如果数据分布不均衡,无法在直方图上表现,看看统计信息头中的rows sampled和rows的差距,可以考虑使用调整采样率或者直接fullscan。
过滤统计信息(filtered statistics)
对于大的表存在数据不均衡,过滤统计信息可以很好的解决这个问题。
注意点:过滤统计信息的更新阀值是基于表的,而不是过滤谓词。
在没有recompile提示之下,过滤索引和过滤统计信息不会被应用到参数化的字段过滤。(In the absence of a RECOMPILE hint, filtered indexes and statistics will not be used in conjunction with parameterization that refers to the filter column.)。
多列统计信息
自动创建统计信息,只会创建单列的,多列统计信息是手工创建的,创建多列统计信息可以提高评估的准确性。提高查询性能。
参数敏感性(Parameter Sensitivity)
参数敏感性是因为数据分布不均衡,参数化的执行计划会以第一次运行的时候的参数来创建,如果数据不均衡,参数变化,会导致执行计划不是很理想的状况。可以加上OPTIMIZE FOR或者RECOPILE来解决。
表变量
在SQL Server 2014上面表变量没有相关的统计信息的,如果要在表变量上存大量的数据建议使用临时表。
多语句用户定义表变量函数
和表变量差不多,多语句表变量函数也没有统计信息,只是用一个固定的基数100。考虑使用内联表变量函数。
内联表变量函数式没有函数体的,直接return 一个表
而多语句表变量函数式有函数体的。
XML Reader表变量函数操作
使用nodes() XQUERY方法如果没有XML索引,会导致很烂的评估,因为XML索引可以带统计信息。解决这个问题的方法是在XML列上加上XML索引。
数据类型转化
如果谓词数据类型,不对会导致数据类型转化,这样也会导致基数评估不准确,是因为列的统计信息无法使用了。
Intra-column比较
Cardinality estimate issues can occur when performing comparisons between columns in the same table. If this is an issue, consider creating computed columns. The computed column can then be referenced in a filter predicate. You can automatically generate the computed column’s associated statistics (by activating automatic statistics creation at the database level) to improve overall estimates. If intra-table column comparison cardinality estimation is a frequent issue, consider normalization techniques (separate tables), derived tables, or common table expressions.
查询提示
尽量避免使用查询提示,查询提示会覆盖优化器的选择,对于某些情况可能会导致更烂的性能。
分布式查询
当通过连接服务器查询数据的时候,如果没有权限访问统计信息的话,会导致查询性能很烂。
在使用前先确定访问统计信息需要多大的权限。
递归CTE
递归CTE也有评估偏差问题,可以看Optimize Recursive CTE Query.
谓词复杂性
避免在谓词列上使用函数或者表达式,这个没啥好说,严重影响性能。
查询复制性
复制的查询也会让评估带来偏差,评估本来就是不准确的,来回怎么倒腾就更加不准确了,应该简化查询。
参考:
Optimizing Your Query Plans with the SQL Server 2014 Cardinality Estimator
SQL Server 2014新特性——基数评估(白皮书阅读笔记)的更多相关文章
- 小心SQL SERVER 2014新特性——基数评估引起一些性能问题
在前阵子写的一篇博文"SQL SERVER 2014 下IF EXITS 居然引起执行计划变更的案例分享"里介绍了数据库从SQL SERVER 2005升级到 SQL SERVER ...
- SQL Server 2014 新特性——内存数据库
SQL Server 2014 新特性——内存数据库 目录 SQL Server 2014 新特性——内存数据库 简介: 设计目的和原因: 专业名词 In-Memory OLTP不同之处 内存优化表 ...
- 谈谈我的微软特约稿:《SQL Server 2014 新特性:IO资源调控》
一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 撰写经历(Experience) 特约稿正文(Content-body) 第一部分:生活中资源 ...
- SQL Server 2014新特性——Buffer Pool扩展
Buffer Pool扩展 Buffer Pool扩展是buffer pool 和非易失的SSD硬盘做连接.以SSD硬盘的特点来提高随机读性能. 缓冲池扩展优点 SQL Server读以随机读为主,S ...
- SQL Server 2014 新特性:IO资源调控
谈谈我的微软特约稿:<SQL Server 2014 新特性:IO资源调控> 2014-07-01 10:19 by 听风吹雨, 570 阅读, 16 评论, 收藏, 收藏 一.本文所涉及 ...
- SQL Server 2014新特性:五个关键点带你了解Excel下的Data Explorer
SQL Server 2014新特性:五个关键点带你了解Excel下的Data Explorer Data Explorer是即将发布的SQL Server 2014里的一个新特性,借助这个特性讲使企 ...
- SQL Server 2014 新特性——内存数据库(转载)
目录 SQL Server 2014 新特性——内存数据库 简介: 设计目的和原因: 专业名词 In-Memory OLTP不同之处 内存优化表 内存优化表的索引 并发能力的提升 和竞争对手相比几点 ...
- [SQL Server 2014] SQL Server 2014新特性探秘
SQL Server 2014新特性探秘(1)-内存数据库 简介 SQL Server 2014提供了众多激动人心的新功能,但其中我想最让人期待的特性之一就要算内存数据库了.去年我再西雅图参加SQ ...
- SQL Server 2014新特性:其他
AlwaysOn 增强功能 SQL Server 2014 包含针对 AlwaysOn 故障转移群集实例和 AlwaysOn 可用性组的以下增强功能: “添加 Azure 副本向导”简化了用于 Alw ...
随机推荐
- Revert R12.1.3 Homepage Layout to Link Style as in R12.1.1 or 11i
https://blogs.oracle.com/ptian/entry/revert_r12_1_3_homepage Oracle EBS 12.1.3主页的展示方式不太习惯,12.1.3为了展示 ...
- Java多线程12:ReentrantLock中的方法
公平锁与非公平锁 ReentrantLock有一个很大的特点,就是可以指定锁是公平锁还是非公平锁,公平锁表示线程获取锁的顺序是按照线程排队的顺序来分配的,而非公平锁就是一种获取锁的抢占机制,是随机获得 ...
- Homework 1 -- The beginning
我是在北京在读的一位大学生.如果问我学的什么专业,我会用一个冷笑话回答你:我精通多种语言,在老家我说家乡话:跟北京我讲普通话:跟老外就玩English:我跟机器得敲代码.现在你知道我学的就是计算机了. ...
- 假如现在有一堆长度大于3小于9的电话号码,用座机呼叫,如果出现这样的号码【123和12345】那么12345将永远不会被拨出,因为拨到123的时候电话已经呼出了,试写一个函数输出所有不能被呼出的电话号码(java实现)
解题: 假如现在有一堆长度大于3小于9的电话号码,用座机呼叫,如果出现这样的号码[123和12345]那么12345将永远不会被拨出,因为拨到123的时候电话已经呼出了,试写一个函数输出所有不能被呼出 ...
- 如何将Icon转成Bitmap
最近工作中有个需求是将Icon转成带Alpha通道的Bitmap, 虽然网上有不少这方面的文章,但很多都是错的, 这里记录下,或许对后来人有用. 要实现这个功能,我们首先需要理解Icon的格式,我们可 ...
- Ubuntu环境搭建系列—WPS/LAMP/Python篇
由于篇幅不宜太长,所以就将此文分成了两部分,在第一部分中我们讲解了google-chrome(谷歌浏览器)的安装,jdk的环境配置,android开发的环境搭建.那么在第二部分中,位们将讲解的是金山W ...
- 在ThoughtWorks工作这几年我学到了什么?
不知不觉,从2012年5月1日加入ThoughtWorks到现在,已经3年有余了.时间过得很快,这三年多我干了很多事情,但仔细想想也没有什么特别值得一提的.在一个公司呆久了总觉得很多事情是理所当然的, ...
- Office 2016 正式发布——新特性预览
今天微软又发生了一件大事!Windows Office 2016正式发布,这标志着Windows Office 又达到了一个新的里程碑! 全新的Office 发布为Office 365 用户带来了新的 ...
- Flash AS实现时钟效果(全脚本实现)
最近工作中用到个Flash效果,好久没有写FlashAS脚本了,就想从以前写的代码中找一些实例.竟然看到硬盘中还留有若干年前的代码. 这个时钟效果是全部采用脚本实现,图形也是用脚本绘制的.写于2005 ...
- linux shell program summary
from:Sep 23 2016 mathematical operation: floating number,bc calculator: we can also use bc in shell ...