基数评估

目录

基数评估

说明

基数评估准确的重要性

模型假设

启用新的基数评估

验证基数评估的版本

在迁移到新的基数评估前要测试

校验基数评估

偏差问题

需要手动处理的变化

避免因为新的CE造成性能下降

SQL Server 2014中的修改

增加多个谓词的相关性的假设

修改超出统计信息范围的评估

Join评估算法修改

Join包含(Containment)假设的修改

不同值计数评估的变化

诊断输出

新基数评估的调优方法

修改数据库兼容级别

使用跟踪标记

基础调优方法

说明

查询优化器的目的是为了找出有效的执行计划,根据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新特性——基数评估(白皮书阅读笔记)的更多相关文章

  1. 小心SQL SERVER 2014新特性——基数评估引起一些性能问题

    在前阵子写的一篇博文"SQL SERVER 2014 下IF EXITS 居然引起执行计划变更的案例分享"里介绍了数据库从SQL SERVER 2005升级到 SQL SERVER ...

  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. Spring声明式事务管理基于@Transactional注解

    概述:我们已知道Spring声明式事务管理有两种常用的方式,一种是基于tx/aop命名空间的xml配置文件,另一种则是基于@Transactional 注解.         第一种方式我已在上文为大 ...

  2. spark on centos6.5 安装

    第一步在centos 6.5上安装java 运行环境 http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-18 ...

  3. 黑马程序员+SQL基础(上)

    黑马程序员+SQL基础 ---------------<a href="http://edu.csdn.net"target="blank">ASP ...

  4. linux系统添加硬盘方法

    [root@wen /]# fdisk -l[root@wen /]# fdisk /dev/sdb[root@wen /]# mkfs -t ext3 -c /dev/sdb1[root@wen / ...

  5. Backbone源码解析(五):Route和History(路由)模块

    今天是四月十二号,距离上次写博已经将近二十天了.一直忙于工作,回家被看书的时间占用了.连续两个礼拜被频繁的足球篮球以及各种体育运动弄的精疲力竭,所以很少抽时间来写技术博客.今天抽出时间把backbon ...

  6. node(md5)

    md5是一种信息-摘要算法,即针对一段明文给出一个hash值,在密码学中最经典的用法是验证数据的完整性,因为一旦原始数据发生改变那么生成的摘要也必将不同. 网络中md5可以用于用户密码的加密,即在数据 ...

  7. 浏览器兼容性小记-DOM篇(一)

    1.childNodes引入空白节点问题:使用childElementCount或children 2.innerText: FF中不支持该属性,使用textContent代替 3.变量名与某HTML ...

  8. 关于大型网站技术演进的思考(十三)--网站静态化处理—CSI(5)

    讲完了SSI,ESI,下面就要讲讲CSI了 ,CSI是浏览器端的动静整合方案,当我文章发表后有朋友就问我,CSI技术是不是就是通过ajax来加载数据啊,我当时的回答只是说你的理解有点片面,那么到底什么 ...

  9. ehcache2拾遗之copyOnRead,copyOnWrite

    问题描述 缓存在提升应用性能,提高访问效率上都是至关重要的一步.ehcache也是广为使用的缓存之一.但是如果将一个可变的对象(如普通的POJO/List/Map等)存入缓存中,会导致怎样潜在的问题. ...

  10. Cocos2d-x 3.X手游开发实例详解

    Cocos2d-x 3.X手游开发实例详解(最新最简Cocos2d-x手机游戏开发学习方法,以热门游戏2048.卡牌为例,完整再现手游的开发过程,实例丰富,代码完备,Cocos2d-x作者之一林顺和泰 ...