将数据库兼容级别更改为 2008 并返回到 2016 可以提高性能 - 怎么可能?

Posted

技术标签:

【中文标题】将数据库兼容级别更改为 2008 并返回到 2016 可以提高性能 - 怎么可能?【英文标题】:Changing database compatibility level to 2008 and back to 2016 improves performance - how can it be? 【发布时间】:2021-06-24 14:07:50 【问题描述】:

我们的客户报告了一个我无法解释的有趣现象:他们将数据库兼容性级别从 2016 年更改为 2008 年,然后回到 2016 年,存储过程中使用的函数的性能显着提高 - 从 9 秒到4.不执行2008兼容的程序,只重置兼容性。

我执行了几次该过程,然后翻转了兼容性,并再次使用相同的参数执行了相同的过程 - 它使用相同的计划,但完成得更快。可能是什么原因? 这是我用来比较性能及其计划的查询。

Query plan

【问题讨论】:

从客户那里得到更新 - 当他们执行更新统计维护工作并创建完整备份时,他们会在第二天早上看到性能下降,这可以通过翻转兼容性级别来解决。但如果备份在更新统计信息之前运行,则不会出现性能问题。我的猜测是内存管理有问题,并且在“更新统计信息然后备份”序列之后它的某些部分变得不可用,并且通过更改兼容性被清除。 【参考方案1】:

可能有一些更新的特性会影响这个旧的存储过程。由于您没有显示代码,因此很难确定问题的根源。

【讨论】:

感谢您的回复毛里西奥!存储过程非常复杂,但我用来跟踪性能变化的一个查询非常简单,并创建了非常简单的计划,该计划使用来自非聚集索引的索引查找。所以问题仍然存在——为什么翻转兼容性级别会改变执行相同操作所需的时间?它发生在执行某些夜间作业(可能更新统计信息)之后。【参考方案2】:

当我们改变一个数据库的兼容级别时,会导致缓存的存储过程计划被移除。例如,当我们在 Adventureworks 数据库中执行以下存储过程时,它会将其插入到计划缓存中。

   EXEC uspGetEmployeeManagers 96

然后我们将更改数据库的兼容性,此操作将删除缓存的存储过程计划。

ALTER DATABASE AdventureWorks2017 SET COMPATIBILITY_LEVEL= 100

因此,在更改数据库的兼容级别后,存储过程将使用新的查询计划。使用新的存储过程查询计划可能会提高查询性能。

【讨论】:

有趣的是,在翻转兼容级别之前和之后使用相同的计划 id,即使它已从缓存中删除。 这些是不同的表。 Query Store 功能将信息写入 sys.query_store_plan 表,您可以查看该表中的 count_compiles 列。

以上是关于将数据库兼容级别更改为 2008 并返回到 2016 可以提高性能 - 怎么可能?的主要内容,如果未能解决你的问题,请参考以下文章

SQL SERVER 2008 如何将字符集更改为UTF-8

尝试将级别更改为高时,命令 npm audit-level 不起作用

将应用的目标 API 级别更改为至少 26

sqlserver2008r2升级到2012的问题

只有在将方向更改为横向并返回纵向后,纵向布局才能正确显示

SQL Server 兼容级别