SQL Server 执行计划利用统计信息对数据行的预估原理二(为什么复合索引列顺序会影响到执行计划对数据行的预估)...

 

本文出处:http://www.cnblogs.com/wy123/p/6008477.html 

  关于统计信息对数据行数做预估,之前写过对非相关列(单独或者单独的索引列)进行预估时候的算法,参考这里。
  今天来写一下统计信息对于复合索引在预估时候的计算方法和潜在问题。
  本文原形来自于是个实际业务问题,某SQL在利用一个符合索引做查询的时候,发现始终会出现预估误差较大的情况,
  而改变复合索引的列顺序,这个预估行数的误差会发生变化,
  也就是说,Create index idx_index1 ON TableName(col1,col2)与Create index idx_index2 on TableName(col2,col1)
  用完全一样的的查询条件做查询,两个索引的执行计划对其预估的行数是不一样的
  究其原因在哪里呢?

  

  先造一个测试环境:

CREATE TABLE TestStatistics
(COL1 INT IDENTITY(1,1)  ,COL2 INT                ,COL3 DATETIME           ,COL4 VARCHAR(50)            
)
GOINSERT INTO TestStatistics VALUES (RAND()*10,CAST(GETDATE()-RAND()*300 AS date),NEWID())
GO 1000000

 

 问题重现

首先看一个非常有意思的问题,
在同一张表上,
先这么建一个索引:CREATE INDEX IDX_COL2_COL3 ON TestStatistics(COL2,COL3)
执行一个查询,预估为4127.86
然后DROP掉上面的索引,继续创建一个索引:CREATE INDEX IDX_COL3_COL2 ON TestStatistics(COL3,COL2)
注意COL2和COL3的顺序不一致
继续执行上面的查询(查询条件不变,数据不变,仅仅是索引列顺序发生了变化),这一次预估为2414.91

 

查询条件一样,数据也一样,为什么改变复合索引列顺序会影响到执行计划对数据行的预估呢?

 

 

 

 

首先来看第一个索引时候的预估算法:

  这个查询他预估为4127.86行,如下图

 

  说起来预估,就离不开统计信息,首先来看IDX_COL2_COL3这个索引的统计信息,
  我们知道,对于复合索引,统计信息中只有前导列的统计数据,也就是说IDX_COL3_COL2这个索引只有COL2这个列的统计信息,如下截图
  对于COL2=2的统计信息,统计为100336行,我们记住这个数字

 

 

  统计信息的另外一个特点就是在会在查询列(非索引列)上自动创建统计信息,如下截图
  查询执行过程中,自动创建了一个名字为:_WA_Sys_00000003_24E8431A的统计信息
  这个统计信息就是对COL3列的统计,可以发现在大于等于2012-10-20之后的统计行数


  在SQL Server 2012中,对数据行的预估计算方式是各个字段的选择性的乘积,
  假如Pn代表不同字段的密度,那么预估行数的计算方法就是: 预估行数=p0*p1*p2*p3……*RowCount
  可以利用这个算法,计算目前数据下,预估出来的结果:4217.86,跟执行计划预估是一致的,非常完美!

 

 

 

    当删除了IDX_COL2_COL3重建建立顺序为COL3+COL2的索引的时候,预估如下

   与上面同样的查询条件,预估为2414.91行

 

   

  依据上面的分析步骤,首先来分析索引列上的统计信息,如下截图为大于等于2016-10-20之后的预估行数

 

 

同理,本次查询也会自动建立COL2列上的统计信息(IDX_COL2_COL3索引被删除),观察这个统计信息对COL2=2的预估为83711.36行

   

   同样我们利用上述公式,来计算预估的行数:2414.9035行,也非常完美地吻合和执行计划预估的结果

   

 

  至此,应该很清楚一开始的问题了,就是为什么复合索引列顺序不一致,在查询的时候导致预估也不一致的原因。
  最根本的原因有就是:
  符合索引上只有前导列的统计信息,查询引擎会根据需要自动创建非前导列的统计信息,
  但是,非常关键一点,如果细心的话,你会发现查询引擎自动创建的统计信息的取样行数都不是100%取样的,这一点非常关键
  正是因为非前导列取样有一定的误差,导致在预估算法的时候,也即 预估行数=p0*p1*p2*p3……*RowCount的时候,密度值是不一样的
  也即在创建IDX_COL2_COL3的时候,统计出来的COL2密度为P1_1,COL3密度为P2_1
  创建IDX_COL3_COL2的时候,统计出来的COL2密度为P1_2,COL3密度为P2_2,因为P1_1<>P1_2,P2_1<>P2_2
  因此,计算出的结果就是P1_1*P2_1<>P2_1*P2_2,原理很简单,希望看官能明白。

  

 

  照这么计算,对于两个顺序不同的统计信息,如果P1_1=P2_1并且P2_1=P2_2,那么乘积就是一样的,预估行数也就是一样的,那么是不是呢?

  


  对于不同顺序的两个索引,先看COL2,COL3顺序的索引
  在查询一次之后(建立了统计信息),执行一个百分之百取样(WITH FULLSCAN)的统计信息更新
  重新来看其预估行数,这一次预估为:2894.49

  

 

 

   删除COL2,COL3顺序的索引,建立COL3,COL2为顺序的索引
  在查询一次之后(建立了统计信息),执行一个百分之百取样(WITH FULLSCAN)的统计信息更新
  重新来看其预估行数,这一次预估为:同样为2894.49,是吻合上述算法

 

 

 

 总结:

  文本简单演示了执行计划利用统计信息预估的算法和原理,以及在计算预估行数时候可能受到的干扰因素,
  这就要求我们在建立索引的时候,不仅仅是说我建一个复合索引就完事了,也要注意其索引列的顺序对执行计划预估的影响,
  更重要的是,要注意查询引擎自动生成的统计信息对预估的影响程度。

  抛开统计信息谈索引的,都是耍流氓。抛开统计信息取样百分比谈统计信息的,也是耍流氓。

  

  引申出来另外一个问题:维护统计信息的时候,能只更新索引列的统计信息,忽略非索引列的统计信息吗?

 

本人技术能力还很菜,写的不对的地方还请各位看官指出,谢谢。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/542313.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机三四级网络技术,全国计算机等级考试四级网络技术论述题真题3

1.(2003年)网络安全策略设计的重要内容之一是&#xff1a;确定当网络安全受到威胁时应采取的应急措施。当我们发现网络受到非法侵入与攻击时&#xff0c;所能采取的行动方案基本上有两种&#xff1a;保护方式与跟踪方式。请根据你对网络安全方面知识的了解&#xff0c;讨论以下…

哈密顿路径_检查图形是否为哈密顿量(哈密顿路径)

哈密顿路径Problem Statement: 问题陈述&#xff1a; Given a graph G. you have to find out that that graph is Hamiltonian or not. 给定图G。 您必须找出该图是否为哈密顿量 。 Example: 例&#xff1a; Input: 输入&#xff1a; Output: 1 输出1 Because here is a …

京东自动下单软件_黄牛软件自动下单秒杀商品 警方用科技手段打击

法制日报全媒体记者 张维定了10个闹钟,也抢不到一瓶茅台&#xff1b;等了很久的iPhone新手机,打开网页就秒没……或许并不是因为你的手速、网速慢,而是黄牛党在用软件和你抢商品。近日,在“净网2019”专项行动中,阿里安全协助江苏省南通市公安局成功打掉了一个制作销售黄牛软件…

Mysql基础之DML语句

增 1 给表的所有字段插入数据 INSERT INTO 表名 VALUES(值1&#xff0c;值2&#xff0c;值3&#xff0c;...&#xff0c;值n)&#xff1b; 2 给表的指定字段插入数据 INSERT INTO 表名(属性1&#xff0c;属性2&#xff0c;...&#xff0c;属性n) VALUES(值1&#xff0c;值2&a…

河南招教考试计算机专业知识,河南教师招聘考试《计算机网络技术基础》知识点归纳七...

河南教师招聘考试《计算机网络技术基础》知识点归纳七1.ADSL是非对称数字用户线路&#xff0c;其下行速率为1.5&#xff5e;8 Mb/s&#xff0c;而上行速率则为16&#xff5e;640 kb/s。在一对铜双绞线上的传送距离可达5km左右&#xff0c;可同时上网打电话&#xff0c;互不影响…

Python程序检查字符串是否是回文

What is palindrome string? 什么是回文字符串&#xff1f; A string is a palindrome if the string read from left to right is equal to the string read from right to left i.e. if the actual string is equal to the reversed string. 如果从左至右读取的字符串等于…

content属性的4种用途

content属性浏览器支持情况&#xff0c;兼容到IE8浏览器&#xff0c;IE7及以下不支持用途一、配合:before及:after伪元素插入文本<div><p>伪元素</p> </div>p:before{content:CSS3;color:#4bb;font-weight:bold;margin-right:20px;background:#f0f0f0;…

内蒙古师范大学计算机科学技术学院,内蒙古师范大学计算机科学技术硕士生导师——李成城...

李成城&#xff0c;教授&#xff0c;硕导&#xff0c;1971年7月出生于内蒙古呼伦贝尔盟。2002年9月-2005年7月在北京邮电大学信息工程学院学习&#xff0c;获得工学博士学位&#xff0c;主要研究领域是&#xff1a;自然语言理解、机器学习、图像识别。1993年在内蒙古师范大学计…

超清世界地图可放大_3D高清世界地图

查看世界地图的工具有哪些可以提供呢&#xff1f;3D世界地图官方版是简单好用的世界地图工具&#xff0c;可以看到地球的大概模样&#xff0c;选择不一样的海洋能看到不一样的事物&#xff0c;这也是一款3d世界地图高清地图&#xff0c;需要用地图软件的可以下载。3D世界地图官…

Java ObjectInputStream readUnshared()方法与示例

ObjectInputStream类readUnshared()方法 (ObjectInputStream Class readUnshared() method) readUnshared() method is available in java.io package. readUnshared()方法在java.io包中可用。 readUnshared() method is used to read "non-shared" or "unshare…

许多计算机英语,计算机英语翻译

1数据是未经组织的事实的集合,数据可以包括单词,数字,图像和声音.2计算机由许多硬件部件构成,这些硬件与软件一起工作,以便执行计算,组织数据及与其他计算机通信的任务,3硬件部件包括输入设备,输出设备,系统单元 ,存储设备和通信设备.4输入设备让用户向计算机存储器输入数据和命…

工欲善其事必先利其器(一)

2019独角兽企业重金招聘Python工程师标准>>> 写在前面的话&#xff1a;纸上得来终学浅&#xff0c;绝知此事要躬行。还是自己敲一遍记得牢。 下载和安装 Emmet为大部分流行的编辑器都提供了安装插件&#xff0c;下面是它们的下载链接&#xff1a; Sublime Text Ecli…

windows 2008r2文件服务器部分用户访问不了_苹果设备如何访问 Windows 文件共享?...

前几天写了一篇关于 Mac 文件共享的。今天继续聊聊 Mac、iPad 和 iPhone 如何访问 Windows 的文件共享。Windows 开启文件共享Windows 搜索并打开「高级共享设置」。在「专用」勾选「启用网络发现」和「启用文件和打印机共享」。然后选择一个 Windows 上想要共享的位置&#xf…

Java文件类boolean isDirectory()方法(带示例)

文件类boolean isDirectory() (File Class boolean isDirectory()) This method is available in package java.io.File.isDirectory(). 软件包java.io.File.isDirectory()中提供了此方法。 This method is used to check whether the file is specified by filepath is a dire…

微信小程序简单入门1

参考文档&#xff1a;https://mp.weixin.qq.com/debug/wxadoc/dev/index.html1 创建项目开发者工具安装完成后&#xff0c;打开并使用微信扫码登录。选择创建“项目”&#xff0c;填入上文获取到的 AppID &#xff0c;&#xff08;无appid直接选择&#xff09;设置一个本地项目…

leetcode数组汇总_LeetCode刷题实战118:杨辉三角

算法的重要性&#xff0c;我就不多说了吧&#xff0c;想去大厂&#xff0c;就必须要经过基础知识和业务逻辑面试算法面试。所以&#xff0c;为了提高大家的算法能力&#xff0c;这个公众号后续每天带大家做一道算法题&#xff0c;题目就从LeetCode上面选 &#xff01;今天和大家…

位运算使奇数+1 偶数-1_C ++程序打印从1到N的所有偶数和奇数

位运算使奇数1 偶数-1Problem: Take input from the user (N) and print all EVEN and ODD numbers between 1 to N. 问题&#xff1a;从用户那里输入(N)&#xff0c;并打印1至N之间的所有偶数和奇数编号。 Solution: 解&#xff1a; Input an integer number (N). 输入一个整…

javascript 模块化机制

1. 概述 js发展初期暴露了其缺陷&#xff1a;缺乏模块&#xff0c;后来提出了commonJS规范来规范其模块的规范。作为JavaScript新手&#xff0c;发现对于其JavaScript的模块机制&#xff0c;不是很理解。我查阅了一些资料整理了JavaScript CommonJS的原理和机制。 2. JavaScrip…

c语言 宏定义 去除宏定义_如何检查是否在C中定义了宏?

c语言 宏定义 去除宏定义To check whether a Macro is defined or not in C language – we use #ifdef preprocessor directive, it is used to check Macros only. 要检查是否用C语言定义了宏 -我们使用#ifdef预处理程序指令&#xff0c;它仅用于检查宏。 Syntax: 句法&…

多线程下不能用truncate吗_那么多的化妆品,怀孕后都不能用了吗?

前几天圆梦参加了青岛的美博会&#xff0c;里面的化妆品真多啊&#xff0c;无论是护肤、美白、彩妆比比皆是&#xff0c;看的人眼&#xff08;liu&#xff09;花&#xff08;lian&#xff09;缭&#xff08;wang&#xff09;乱&#xff08;fan&#xff09;。虽说国务院宣布的新…