我有几乎相同的表,行数差异很小。一个在 2012 年,另一个在 2016 年。索引是相同的。这些 VM 与升级的 OS 和 SQL Server 版本处于完全相同的环境中。相同数量的 vcores,相同的内存,相同的服务器设置(最大并行度 = 8,并行度的成本阈值 = 30)。
这个简单的单条记录查询使用单列进行过滤和单列返回。where 过滤器中的列是索引中的唯一列。
2016 版有 8254356 行
2012 版有 8254427 行
它们是相同的查询。2016 缺少索引并无缘无故地进行全表扫描。2012 在索引扫描后对表进行 RID 查找(堆)。
我WITH (index = CONTACT_RC_NUI1)
在2016服务器上试过,成本从991跳到1889。2012的成本是29。
我尝试添加AND 1 = (SELECT 1)
,但没有任何区别。
我尝试通过使用删除参数嗅探作为可能的问题OPTION (RECOMPILE)
,但没有任何区别。
DBA 在恢复数据库后运行索引重建。两台服务器都有最近的索引统计更新(我们运行 Ola 的索引更新脚本)。并且可以肯定的是,我在 2016 年重建了索引,这对 2016 年的解释计划没有影响。
我在查询中添加了以下提示...
select address1_stateorprovince
from dla.dcrm.CONTACT_RC WITH (index = CONTACT_RC_NUI1)
where wv_partyid = 343083;
Run Code Online (Sandbox Code Playgroud)
这导致成本从 991 增加到 1889,即使它显示与 2012 年的解释计划几乎相同(2016 年只是添加了并行性(收集流))。
2016 …
在我们的 2 个生产数据库上启用了查询存储,但由于我的 SA 权限被撤销(我暂时将它们用于新服务器),因此我不再有权查看数据库下的查询存储节点。
我找不到任何描述访问查询存储报告所需的最低权限的地方。
有没有人知道或知道将执行通用临时表操作以便历史记录和主表都被截断的存储过程?
您必须更改它以设置 system_versioning = off,然后删除历史表,然后截断主表,然后在主表上重新启用版本控制。我打算构建一个通用存储过程来为传递给它的任何数据库/模式/表名称执行此操作,但如果有人已经拥有它,肯定会很好。如果可以避免的话,我从不喜欢重新发明轮子。