我正在使用dbcc show_statistics在我的直方图中寻找倾斜数据并提高我的统计质量。
OPTIMIZE FOR UNKNOWN不使用值 - 相反,它使用密度向量。
如果您运行DBCC SHOWSTATISTICS ,则它是第二个结果集的“所有 密度”列中列出的值。
在下图中,由于数据倾斜,估计的行数与实际的行数存在差异。
这谈到了 @variables 和recompile,它们可以提供帮助并且是解决方案的一部分。
问题:
如何在缓存的执行计划中找到估计行数与实际行数有差异的查询?
没有完美的答案。首先,也是最重要的,弄清楚您可能需要手动刷新统计数据的次数、频率和方式。自动维护对于 80-90% 的统计数据来说已经足够了,但对于其余的数据来说就严重不足了,所以第一步,让手动更新参与进来。频率实际上取决于您的数据和变化率。此外,采样与全扫描,您必须根据您的数据、分布和变化率来确定另一件事。
完成后,您可能仍然会看到偏差,并认为它会对您的查询性能产生负面影响。有很多可能的工具可以解决这个问题,没有一个是“完美无缺,一刀切”的解决方案。相反,一切都是“视情况而定”。
一种方法是重新编译(请在语句级别)提示。但是,这会增加处理器的开销,因为它将重新编译计划。它还会对计划重用产生负面影响,因为您看不到任何内容。
另一种方法是使用优化器提示、OPTIMIZE FOR、UNKNOWN(如果数据的平均值更好),或者一个值(如果更具体的计划可行)。再次,更多的测试。
如果您运行的是 SQL Server 2016 或更高版本,另一个工具是使用查询存储和计划强制。类似于使用 OPTIMIZE FOR 一个值,但不需要更改代码,所以这是一个胜利。
SQL Server 2022 即将推出,它还具有自动执行查询存储计划强制的参数敏感计划调整(这很酷,非常酷,但不会解决所有问题)。
最后,您还可以使用过滤统计信息或过滤索引来为特定查询创建特定统计信息。这是很多工作,但可以解决问题。再次,测试。
这些中的任何一个都可以工作,但它们都不会一直工作。您必须准备好根据情况尝试不同的解决方案。
至于查询估计值与实际值,您遇到的问题是缓存和查询存储中的计划不保存运行时指标,因此无法使用它们进行比较。但是,如果您运行的是 SQL Server 2019、CTP 2.4 或更高版本,则可以使用sys.dm_exec_query_plan_stats查看带有运行时指标的最后一个计划。这并不完美,因为一次执行可能与估计匹配,而下一次不匹配,但这是解决此问题的最简单方法。否则,我真的不建议这样做,您必须使用扩展事件捕获计划才能进行比较。