自动采样的统计更新弄乱了密度向量和直方图

Mat*_*ino 6 sql-server statistics sql-server-2016

我有一个包含 2200 万条记录的表。

我注意到一列的统计数据很差,即使该列具有恒定分布:实际上,每个值都重复两次。

为了帮助您可视化此场景,请考虑一个表,其中包含另一个表的每个唯一 ID 的签入和签出日期(2 个不同的记录)。

这些是完整扫描的统计信息:全扫描统计

这些是自动采样的统计数据:在此处输入图片说明

为什么会有这种奇怪的行为?是否有一些经验法则可以确定正确的采样率,或者是否需要全扫描?我应该为某些统计信息创建一个带有 fullscan 的统计更新作业吗?如果是这样,我怎么知道哪些统计数据需要这种处理?

附加信息:

  • 该列没有外键约束
  • 该列是一个 numeric(14,0) NULL

Joe*_*ish 5

为什么会有这种奇怪的行为?

假设有人给了你一本包含一百万个整数的书,并告诉你根据十个采样数字来猜测总体分布。您收到的十个采样数字是 1、1、125000、125000、250000、250000、375000、375000、500000 和 500000。一个完全合理的猜测是,这本书包含 500000 个唯一整数,成对范围从 1 到 500000。同样有效的猜测是这本书包含 5 个唯一的整数,每个整数出现 200000 次。对于您的数据分发,SQL Server 会根据更接近后一种解释的示例对您的数据进行推断。构建直方图的算法并不适用于所有可能的采样数据分布,包括每个唯一整数恰好出现两次的分布。我能够轻松地在 SQL Server 2017 中重现您所描述的问题。

是否有一些经验法则来确定正确的采样率,或者是否需要进行全扫描?

我所知道的唯一经验法则是,正确的采样率至少等于为您提供可接受的查询或系统性能的采样率。我发现 DBA 使用 100% 采样率来避免这种分析,对于不太大的表来说,这是一个完全合理的捷径。

您可以考虑使用基于两个基础表构建的可更新视图替换您的表。每个基础表可以包含一半的数据。SQL Server 将为每个表构建单独的统计对象,您无需调整统计信息即可获得更好的性能。我不能说这对于您的具体情况是否是一个好方法。

我应该使用全扫描创建统计更新作业来获取某些统计信息吗?

这是您所描述的问题的常见解决方案。对于另一个选项,SQL Server 2016 SP1 CU4 引入了命令的PERSIST_SAMPLE_PERCENTSTATISTICS关键字。您可以使用它来指示 SQL Server 在触发自动统计更新时始终以特定速率对该列进行统计采样。如果禁用异步统计信息更新,请记住,对于使用您的列的查询,查询编译时间有时可能会很长。

如果是这样的话,我怎么知道哪些统计数据需要这种处理?

通常的答案是监视工作负载是否存在不可接受的查询性能,确定哪些查询存在统计问题,并通过统计更改来修复这些问题。如果您希望积极主动,可以考虑分析生产副本的统计数据。首先获取数据库中所有相关列的采样统计信息,并将所有密度向量保存到表中。你可以用DBCC SHOW_STATISTICS WITH DENSITY_VECTOR它来做到这一点。然后更新所有相同的统计数据FULLSCAN并保存这些密度向量。然后,您可以比较密度向量以找到差异最大的统计对象。这不会找到所有统计问题,但会找到与您在这个问题中观察到的类似的问题。