我正在对同步与异步自动统计更新进行一些测试。我想快速使所有统计对象(标题、密度向量和直方图)失效,以确保下次使用统计时会更新它。
我正在尝试模拟统计信息的自动更新,而不是自动创建。
理想情况下,我不想更改行数,所以我已经取消了INSERT/DELETE
操作。理想情况下,我也不想更改任何数据值,我考虑过使用UPDATE
语句,但我认为这在我的一些较大的表上可能会花费太长时间。
我看过UPDATE STATISTICS WITH ROWCOUNT, PAGECOUNT
但我不认为这是我所追求的。我希望可能有一个跟踪标志或未记录的命令会使统计信息无效。
有没有一种快速、有效的方法来完成我想实现但我没有考虑过的事情?
我正在 SQL Server 2016 上进行测试。
我能找到的导致自动统计信息更新的最可靠序列是:
更新对零行采样的统计信息
这会导致一个空的统计对象。
更新表的单行中的目标列
这会增加列修改计数器。空统计对象和递增修改计数器的组合启用特殊情况统计更新(它模拟在空表上创建统计,然后添加一行)。
运行查询
OPTION (RECOMPILE)
这会导致自动更新检测到的陈旧统计信息,即使查询的匹配计划已存在于缓存中。如果再次匹配,生成的统计信息更新随后将导致对原始缓存计划进行基于最优性的重新编译。
演示
使用与jyao 的答案中使用的类似AdventureWorks查询,以下脚本将以上所有内容放在一起:
输出
结果
DBCC SHOW_STATISTICS
显示原始统计头、空头和过程结束时所需的更新头:不确定下面的方法是否能满足你的要求,我想你可以尝试这样做:
这实际上会清除您统计信息中的所有信息(它们本身是 sql server 对象并且仍然存在,即不删除统计信息本身)
根据MSDN
对我来说,清空你的统计数据可以被认为是一种让你的统计数据“无效”的方法。:-)
[更新] 我在 SQL2014 上做了一个快速测试,如下所示:
我可以看到以下内容
然后我可以运行以下
我将得到一个执行计划如下
现在我将执行以下操作
我会看到统计数据被清除。
现在如果我跑
我会得到一个不同的执行计划。
我刚刚想到但最初没有考虑的另一种方法是使用非更新更新来修改足够的行以触发阈值,这可以使用类似于以下 T-SQL 的方法来实现: