sql-server - 解释 SQL Server 表统计信息
问题描述
我编写查询和程序,我没有作为数据库管理员的经验,而且我无法做到这一点。我使用数百张表,某些旧表很难使用。我怀疑统计数据是个问题,但 DBA 表示情况并非如此。
我不知道如何解释统计数据,甚至不知道应该查看哪些统计数据。例如,我目前正在 JOINing 2 个表,它是一个使用索引的简单 JOIN。
它在 4 列中返回不到 500 行。它运行得非常快,但在每天运行数千次的生产中却不是。我在这个 JOIN 上的估计行和实际行减少了 462%。
我已经将这个存储过程提炼成很多非常基本的临时表来定位问题区域,它似乎是 2 个表,这个例子就是其中之一。
我想知道的是要运行哪些命令以及要查看哪些统计信息以供 DBA 讨论手头的具体问题。我不想对抗,但要提供信息。我与这位 DBA 有着非常好的专业关系,但他的政策是非黑即白的,所以我最终可能不会得到任何结果,但如果我遇到阻碍,我也可以把它带上我的领导地位。
我在DBCC SHOW_STATISTICS
表的索引上运行了一个。我不确定这是我需要的数据还是我真正在看的数据。我真的很想知道从哪里开始。我用谷歌搜索过,但我阅读的所有页面都非常适合 DBA,并假设我在没有领域的先验知识。
下面是我的 JOIN 混淆示例 - 我的 JOIN 在临时表上,索引需要前 2 个条件,删除时的日期条件使 JOIN 实际上变得更糟,读取量是 10 倍:
SELECT
x.UniqueID,
x.ChargeCode,
x.dtDate,
x.uniqueForeignID
INTO
#AnotherTempTable
FROM
Billing.dbo.Charges x
JOIN
#temptable y ON x.uniqueForeignID = y.uniqueID
AND x.ChargeCode = y.ChargeCode
AND @PostMonthStart <= x.dtDate
AND x.dtDate < @PostMonthEnd
上面的 JOIN 是一个新计划的一部分,我一直在剖析临时表所需的所有数据,以确定高 CPU 和生产中读取问题的根本原因。下面是正在执行的所有语句的列表,按读取次数排序。第二行是此示例查询,但还有其他类似问题。
以下是我更新之前计划的执行计划操作。
虽然新计划有更好的运行时间和更接近的估计,但我担心如果统计数据关闭,我仍然会遇到问题。如果我完全偏离基础,请告诉我并指出正确的方向,如果我做出不正确的假设,我会很高兴地找出另一棵树。
解决方案
返回的第一个表显示了一些一般信息。您可以看到该指数的统计数据最后更新时间为 2019 年 12 月 25 日晚上 10:19。截至撰写此答案时,即昨天晚上,因此最近更新了统计信息。这可能是某种晚间维护,但也可能是触发自动统计更新的数据修改阈值。
在对统计数据进行抽样时,表中有 222,596,063 行。统计更新对这些行中的 626,452 行进行了抽样,因此抽样率为 0.2%。这个样本大小可能是一个简单update statistics MyTable
命令使用的默认采样率。
0.2% 的采样率计算速度很快,但可能导致非常糟糕的估计——尤其是在使用索引来支持外键的情况下。例如,父/子关系可能ParentKey
在子表上有一个列。低统计采样率将导致每个父行的估计值非常高,这可能导致查询计划中的奇怪决策。
查看第三张表(直方图)。对应于该RANGE_HI_KEY
索引中第一列的特定键值。该EQ_ROWS
列是直方图对与此键对应的行数的估计。如果您通过 RANGE_HI_KEY 列中的这些键之一获得此表中的行数,那么 EQ_ROWS 列中的数字是否看起来像一个准确的估计值?如果不是,更高的采样率可能会产生更好的查询计划。
例如,取值 1475616。此键的行数是否接近 EQ_ROWS 值 3893?
select count(*) from MyTable where FirstIndexColumn = 1475616
如果估计很差,DBA 可能需要增加这张表的样本量:
update statistics MyTable with sample 5 percent
如果 DBA 使用Ola Hallengren 的计划(我认为这是一个很好的选择),这可以通过将@StatisticsSample
参数传递给IndexOptimize
过程来完成。
推荐阅读
- html - 粘性侧边栏在 Firefox 中没有正确的顶部空间
- c# - 鉴于一台服务器上的 ASP.Net MVC 站点但另一台服务器上的 ASP.Net MVC 站点,HttpContext.Current.User.Identity 为空/空
- python - 芹菜任务的 finally 子句不执行,我该如何清理?
- python - Pandas Dataframe 到嵌套数据结构
- node.js - 带有Angular的Node.js - 我发送请求时出现CORS错误
- github - GitHub 发布模板
- sas - 在 SAS 中使用变量命名导出的文件
- php - 为什么不能在我的函数中调用我的全局变量?
- python - 在 Python 模块中运行无限 while 循环
- excel - 当过滤表列中的单元格都不是空白时,如何运行 VBA 代码?