iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >SQL Server如何统计信息更新时采样百分比对数据预估准确性的影响
  • 509
分享到

SQL Server如何统计信息更新时采样百分比对数据预估准确性的影响

2024-04-02 19:04:59 509人浏览 安东尼
摘要

这篇文章将为大家详细讲解有关SQL Server如何统计信息更新时采样百分比对数据预估准确性的影响,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。为什么要写统计信息最近看到

这篇文章将为大家详细讲解有关SQL Server如何统计信息更新时采样百分比对数据预估准确性的影响,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

为什么要写统计信息

最近看到园子里有人写统计信息,楼主也来凑热闹。

话说经常做数据库的,尤其是做开发的或者优化的,统计信息造成的性能问题应该说是司空见惯。

当然解决办法也并非一成不变,“一招鲜吃遍天”的做法已经行不通了(题外话:整个时代不都是这样子吗)

当然,还是那句话,既然写了就不能太俗套,写点不一样的,本文通过分析一个类似实际案例来解读统计信息的更新的相关问题。

对于实际问题,不但要解决问题,更重要的是要从理论上深入分析,才能更好地驾驭数据库

何时更新统计信息

(1)查询执行缓慢,或者查询语句突然执行缓慢。这种场景很可能是由于统计信息没有及时更新而遭遇了参数嗅探的问题。

(2)当大量数据更新(INSERT/DELETE/UPDATE)到升序或者降序的列时,这种情况下,统计信息直方图可能没有及时更新。

(3)建议在除索引维护(当你重建、整理碎片或者重组索引时,数据分布不会改变)外的维护工作之后更新统计信息。

(4)数据库的数据更改频繁,建议最低限度每天更新一次统计信息。数据仓库可以适当降低更新统计信息的频率。

(5)当执行计划出现统计信息缺失警告时,需要手动建立统计信息

统计信息基础

首先说一个老掉牙的话题,统计信息的更新阈值:

1,表格从没有数据变成有大于等于1条数据。

2,对于数据量小于500行的表格,当统计信息的第一个字段数据累计变化量大于500以后。

3,对于数据量大于500行的表格,当统计信息的第一个字段数据累计变化量大于500 + (20%×表格数据总量)以后。

SQL Server如何统计信息更新时采样百分比对数据预估准确性的影响

做个查询,触发统计信息更新,rowmodct归0(继续累积直到下一个触发的阈值,触发更新之后再次归0)

SQL Server如何统计信息更新时采样百分比对数据预估准确性的影响

关于统计信息“过期”的问题

下面开始正文,网络上很多关于统计信息的文章,提到统计信息,很多都是统计信息过期的问题,然后跟新之后怎么怎么样

尤其在触发统计信息自动更新阈值的第三个区间:也就是说数据累计变化超过20%之后才能自动触发统计信息的更新

这一点对于大表来说通常影响是比较大的,比如1000W的表,变化超过20%也+500也就是200W+500行之后才触发统计信息更新,这个阈值区间的自动触发阈值,绝大多数情况是不能接受的,于是对于统计信息的诊断就变成了是否“过期”

SQL Server如何统计信息更新时采样百分比对数据预估准确性的影响

判断统计信息是否过期,然后通过更新统计信息来促使执行计划更加准确地预估行数,这一点本无可厚非

但是,问题也就出在这里了:那么怎么更新统计信息?一成不变的做法是否可行,这才是问题的重点。

当然肯定有人说,我就是按照默认方式更新的,更新完之后sql也变得更加优化了什么的

通过update statistics TableName StatisticName更新某一个索引的统计信息,

或者update statistics TableName更新全表的统计信息

这种情况下往往是小表上可以这么做,当然对于大表或者小表没有一个标准值,一切要结合事实来说明问题

下面开始本文的主题:

抽象并简化出业务中的一个实际案例,创建这么一张表,类似于订单和订单明细表(主子表),

这里你可以想象成是一个订单表的子表,Id字段是唯一的,有一个ParentID字段,是非唯一的,

ParentID类似于主表的Id,测试数据按照一个主表Id对应50条子表明细的规律插入数据

CREATE TABLE [dbo].[TestStaitistiCSSample](
 [Id] [int] IDENTITY(1,1) NOT NULL,
 [ParentId] [int] NULL,
 [OtherColumn] [varchar](50) NULL
) 


declare @i int=0
while(@i<100000000)
begin

 insert into [TestStaitisticsSample](ParentId,OtherColumn)values(@i,NEWID())
 
 insert into [TestStaitisticsSample](ParentId,OtherColumn)values(@i,NEWID())

 set @i=@i+1
end
Go

create nonclustered index [idx_ParentId] ON [dbo].[TestStaitisticsSample]
(
 [ParentId] 
)
go

本来打算插入1亿条的,中间我让他执行我睡午觉去了,醒来之后发现SSMS挂掉了,挂掉了算了,数据也接近1亿了,能说明问题就够了

现在数据分布的非常明确,就是一个ParentId有50条数据,这一点首先要澄清。

测试数据写入,以及所创建完成之后来更新idx_ParentId 索引上的统计信息,就按照默认的方式来更新,然后来观察统计信息

默认方式更新统计信息(未指定采样密度)

表里现在是8000W多一点记录,默认更新统计信息时取样行数是462239行,那么这个统计信息靠谱吗?

上面说了,造数据的时候,我一个ParentId对应的是50行记录,这一点非常明确,他这里统计出来的多少?

1,对于取样的RANG_HI_Key值,比如51632,预估了862.212行

2,对于AVG_RANG_ROW,比如45189到51632之间的每个Id的数据对应的数据行,预估是6682.490行

之前造数据的时候每个Id都是50行,这里的预估靠谱吗,这个误差是无法接受的,

很多时候,对于大表,采用默认(未指定采样密度)的情况下,默认的采样密度并不足以准确地描述数据分布情况

SQL Server如何统计信息更新时采样百分比对数据预估准确性的影响

指定一个采样密度的方式更新统计信息(20%采样)

这一次用20%的采样密度,可以看到取样的行数是15898626行

1,对于取样的RANG_HI_Key值,比如216305,他给我预估了24.9295行

2,对于AVG_RANG_ROW,比如186302到216305之间的每个Id的行数,预估是197.4439行

观察比如上面默认的取样密度,这一次不管是RANG_HI_Key还是AVG_RANG_ROW得预估,都有不一个非常高的下降,开始趋于接近于真实的数据分布(每个Id有50行数据)

整体上看,但是这个误差还是比较大的,如果继续提高采样密度,看看有什么变化?

SQL Server如何统计信息更新时采样百分比对数据预估准确性的影响

指定一个采样密度的方式更新统计信息(70%采样) 

这一次用70%的采样密度,可以看到取样行数是55962290行

1,对于取样的RANG_HI_Key值,比如1978668,预估了71.15906行

2,对于AVG_RANG_ROW,比如1124024到1978668之间的每个Id,预估为61.89334行

可以说,对于绝大多数值得预估(AVG_RANG_ROW),都愈发接近于真实值

  SQL Server如何统计信息更新时采样百分比对数据预估准确性的影响

指定一个采样密度的方式更新统计信息(100%采样)

可以看到,取样行数等于总行数,也就是所谓的全部(100%)取样

看一下预估结果:

比如Id=3981622,预估是50行,3981622与4131988之间的Id的行数,预估为49.99874行,基本上等于真实数据分布

这个就不做过多解释了,基本上跟真实值是一样的,只是AVG_RANG_ROW有一点非常非常小的误差。

SQL Server如何统计信息更新时采样百分比对数据预估准确性的影响

取样密度高低与统计信息准确性的关系

至于为什么默认取样密度和较低取样密度情况下,误差很大的情况我简单解释一下,也非常容易理解,因为“子表”中存储主表ID的ParentId值允许重复,在存在重复值的情况下,如果采样密度不够,极有可能造成“以偏概全”的情况

比如对10W行数据取样1W行,原本10W行数剧中有2000个不重复的ParentId值,如果是10%的取样,在1W行取样数据中,因为密度不够大,只找到了20个不重复的ParentId值,那么就会认为每一行ParentId对应500行数据,这根实际的分布的每个ParentId有一个非常大的误差范围

如果提高采样密度,那么这个误差就会越来越小。  

更新统计信息的时候,高比例的取样是否可取(可行) 

因此在观察统计信息是否过期,决定更新统计信息的时候,一定要注意取样的密度,就是说表中有多少行数据,统计信息更新的时候取了多少采样行,密度有多高。

当然,肯定有人质疑,那你说采样密度越高,也就是取样行数越高越准确,那么我就100%取样。

这样行不行?

还要分情况看,对于几百万或者十几万的小表来说,当然没有问题,这也是为什么数据库越小,表数据越少越容易掩盖问题的原因。

对于大表,上亿的,甚至是十几亿的,你按照100%采样试一试? 

举个实际例子:

我这里对一个稍微大一点的表做个全表统计信息的更新,测试环境,服务器没负载,存储是比普通的机械硬盘要强很多的SAN存储

采用full scan,也就是100%采样的更新操作,看一下,仅仅这一样表的update statistic操作就花费了51分钟

试想一下,对一个数百GB甚至数TB的库来说,你敢这么搞一下。

  SQL Server如何统计信息更新时采样百分比对数据预估准确性的影响

扯一句,这个中秋节过的,折腾了大半天,话说做测试过程中电脑有开始有点卡,

做完测试之后停掉SQLServer服务,瞬间内存释放了7个G,可见这些个操作还是比较耗内存的

 SQL Server如何统计信息更新时采样百分比对数据预估准确性的影响  

关于“SQL Server如何统计信息更新时采样百分比对数据预估准确性的影响”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

您可能感兴趣的文档:

--结束END--

本文标题: SQL Server如何统计信息更新时采样百分比对数据预估准确性的影响

本文链接: https://www.lsjlt.com/news/56421.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • oracle怎么查询当前用户所有的表
    要查询当前用户拥有的所有表,可以使用以下 sql 命令:select * from user_tables; 如何查询当前用户拥有的所有表 要查询当前用户拥有的所有表,可以使...
    99+
    2024-05-15
    oracle
  • oracle怎么备份表中数据
    oracle 表数据备份的方法包括:导出数据 (exp):将表数据导出到外部文件。导入数据 (imp):将导出文件中的数据导入表中。用户管理的备份 (umr):允许用户控制备份和恢复过程...
    99+
    2024-05-15
    oracle
  • oracle怎么做到数据实时备份
    oracle 实时备份通过持续保持数据库和事务日志的副本来实现数据保护,提供快速恢复。实现机制主要包括归档重做日志和 asm 卷管理系统。它最小化数据丢失、加快恢复时间、消除手动备份任务...
    99+
    2024-05-15
    oracle 数据丢失
  • oracle怎么查询所有的表空间
    要查询 oracle 中的所有表空间,可以使用 sql 语句 "select tablespace_name from dba_tablespaces",其中 dba_tabl...
    99+
    2024-05-15
    oracle
  • oracle怎么创建新用户并赋予权限设置
    答案:要创建 oracle 新用户,请执行以下步骤:以具有 create user 权限的用户身份登录;在 sql*plus 窗口中输入 create user identified ...
    99+
    2024-05-15
    oracle
  • oracle怎么建立新用户
    在 oracle 数据库中创建用户的方法:使用 sql*plus 连接数据库;使用 create user 语法创建新用户;根据用户需要授予权限;注销并重新登录以使更改生效。 如何在 ...
    99+
    2024-05-15
    oracle
  • oracle怎么创建新用户并赋予权限密码
    本教程详细介绍了如何使用 oracle 创建一个新用户并授予其权限:创建新用户并设置密码。授予对特定表的读写权限。授予创建序列的权限。根据需要授予其他权限。 如何使用 Oracle 创...
    99+
    2024-05-15
    oracle
  • oracle怎么查询时间段内的数据记录表
    在 oracle 数据库中查询指定时间段内的数据记录表,可以使用 between 操作符,用于比较日期或时间的范围。语法:select * from table_name wh...
    99+
    2024-05-15
    oracle
  • oracle怎么查看表的分区
    问题:如何查看 oracle 表的分区?步骤:查询数据字典视图 all_tab_partitions,指定表名。结果显示分区名称、上边界值和下边界值。 如何查看 Oracle 表的分区...
    99+
    2024-05-15
    oracle
  • oracle怎么导入dump文件
    要导入 dump 文件,请先停止 oracle 服务,然后使用 impdp 命令。步骤包括:停止 oracle 数据库服务。导航到 oracle 数据泵工具目录。使用 impdp 命令导...
    99+
    2024-05-15
    oracle
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作