表值函数从 2012 年迁移到 sql 2017 后性能下降
Posted
技术标签:
【中文标题】表值函数从 2012 年迁移到 sql 2017 后性能下降【英文标题】:Performance hit after migrating to sql 2017 from 2012 for Table-valued-functions 【发布时间】:2019-06-17 14:27:05 【问题描述】:一个月前从 2012 年迁移到 2017 年(测试似乎还可以,但测试不严格)。一个月后,我注意到以一系列常用表表达式开头的表值函数需要很长时间才能执行或根本不执行。我可以重写代码(第 3 方应用程序以及我们自己的自定义代码并排......哎哟)。我今天注意到的是,一个查询在 SQL2012 服务器上运行良好(我仍然可以访问它)并且完全在 SQL2017 上出去吃午饭。我认为这可能会发生并保留所有数据库的兼容性设置。有没有人遇到过这个?
我玩过 9481,但据我所知,使用 Comp Level 110,这甚至不应该是一个问题。是否有任何其他服务器设置我可以设置以强制它表现得像它那样处理问题(有很多)一个接一个。
此外,由于这些 tvf 表在任何地方都可以重复使用和引用,因此保持原样很重要。我不能过多地重新布置家具。开发人员同时利用了 TVF 和 CTE。
一个月前从 2012 年迁移到 2017 年,兼容性保持不变。模式已经发展起来,查询:
Select t1.Col1
t1.Col2,t2.Col8,
tvfTable1.Col10, etc...
FROM table1 t1 join table2 t2 on t1.key=t2.foreignkey
CROSS APPLY (t1.Col1,t2,col4,0,1,2,3) tvfTable1
TVF 的一切似乎都始于:
...
AS RETURN (
WITH CTE1 AS (query),
CTE2 AS (query referencing CTE1)
...
SELECT MANYColumns
FROM MANYTABLES JOIN CTE4 on mt.key=cte4.key
【问题讨论】:
诊断差异的良好开端始终是获取一个执行与另一个执行的执行计划。如果查询在 2017 年根本不会返回,您至少可以获得一个估计的执行计划,该计划将显示基本方法是否相同(可能不会)。保持兼容性级别不会完全使优化器的行为与 2012 年相同;获得完全相同行为的唯一保证方法是不升级(当然,出于其他原因,这是不可取的......) 谢谢。是的,我真的不想分析计划。一团糟。引用 tvf 的 tvf 表...在我到达基表之前大约 3 或更深。这些计划是不可能阅读的。我知道我可以重写查询以更快,但我不能重写每一个。我需要一颗灵丹妙药。 恐怕你不可能得到一个。特别是,没有“请完全按照我在这里得到的其他服务器的行为”跟踪标志。您至少应该分析 one 查询的 one 实例以比较 2012 年和 2017 年,以了解实际问题是什么——基数估计?新的统计数据?并行度的不同使用?有些事情可能会承认服务器级别的实际修复/调整,有些可能不会。您不必自己分析计划 - 获取它们,paste them,看看这里是否有聪明人可以做到。 我总是要检查的第一件事:看看您是否安装了最新的 SP/CU。接下来,Jeroen 的建议。 哦,还有一个更便宜且显而易见的方法可以尝试——如果您不保持兼容级别并允许新的优化器伸展腿脚怎么办?换句话说,将兼容级别提高到 140,看看情况是否有所改善。显然,如果您的数据库中有任何可能损坏的东西,您可能想要check - 损坏的更改不多,但有一些。 【参考方案1】:就像 Jaroen 已经评论的那样,任何性能问题问题都可以在至少以下时间得到最好的建议:
底层表数据量信息
基础表和索引结构
提供了执行计划屏幕截图或详细信息。
由于提供的详细信息有限,您可以尝试以下几点:
-
在运行查询时,请通过以下方式检查服务器中的等待统计信息
在 dmvs 查询:sys.dm_os_wait_stats 和 sys.dm_tran_locks。请
检查等待是否是由于 CXPACKET(由于其他
并行进程)或 PAGEIOLATCH(从磁盘读取而不是从 RAM 读取)或
锁。这是调查的起点
你是根本原因,然后你可以采取适当的措施
相应地。
请检查您的新服务器中的统计信息是否已更新。如果不,
请更新基础表的统计信息(尝试使用 FULLSCAN
如果可能的话,如果您在迁移后没有更新统计信息
到新服务器)
请确保结构(包括索引)和 两台服务器中基础表的数量相同且没有 服务器迁移过程中发生意外。
您能否确定您的 MAXDOP 配置是否经过优化 关于你在新的逻辑处理器的数量 服务器?
我还想问你 2 之间的 RAM 差异 服务器。你能检查每台服务器的“可用内存”吗 当您执行相同的查询时?
理想情况下,如果可能的话,我建议您转向兼容性 尽快2017级,因为很长一段时间, 兼容性级别只影响 T-SQL 的解释方式 并且不必对性能做任何事情。但从 SQL Server 2014,我们得到新的基数估计和其他 改进执行计划的构建方式。并且通过改变 那,我们突然为许多查询得到了不同的查询计划 可以比旧的执行计划执行得更快 正在生成兼容级别 2012 或更早版本。通常 在 SQL Server 升级期间,建议最初应该 保持原来的兼容级别。一旦它运行良好1-2 服务器升级几周后,我们可以设置兼容级别 将 SQL Server 升级到开发服务器中的最新版本并进行测试 如果一切正常。之后,兼容性级别 可以在生产环境中升级到最新版本。 这是一篇关于不同版本的 TVF 性能的文章 SQL 服务器: https://www.mssqltips.com/sqlservertip/5728/sql-server-multi-statement-table-value-function-mtvfs-performance-difference-between-versions/【讨论】:
谢谢桑。我认为部分问题在于它的第三方软件。但这提醒我,我需要重新审视分层存储问题。这是提供商的虚拟机。我没有真正的服务器管理员可以交谈,就像我在其他工作中一样。但有人告诉我,我们有墙到墙的 SSD 磁盘。所以,我抓住了一个机会,将数据和日志放在同一个卷上。我可能会重新考虑。我有一些针对 AVG 磁盘队列长度运行的性能计数器,我只在备份时间看到排队。但我可能会在明天重新讨论。我可以相当快地获得一个单独的日志卷并将它们移到那里 @Bukester 告诉我进展如何。我也有兴趣了解您对上述项目#1、#2、#3 的发现。如果有帮助,请随时为答案投票。 :-)【参考方案2】:谢谢大家。似乎我犯了一个错误,当我认为它是 110 时,我已经将兼容性级别设置为 140。所以,我最初的困惑是,在旧级别的行为怎么会如此糟糕。我把它移回了 110,现在事情是可以预测的。 tvf 从来都不是很好,但在 140 时,它太可怕了。我们有很多工作要做。
【讨论】:
以上是关于表值函数从 2012 年迁移到 sql 2017 后性能下降的主要内容,如果未能解决你的问题,请参考以下文章
Team Foundation 数据从 TFS2010/SQL Server 2008R2 迁移到 TFS2012/SQL Server 2012 服务器