一点背景:
我们正在迁移到一个比旧版本更高规格的新SQL服务器,并且包含新版本的SSMS(2014)。
每天都有无数次使用的视图。在旧服务器上运行时,它一直需要大约1分30秒,而在新服务器上则需要更长的时间;通常5分钟左右。
SELECT v1.*
FROM view1 v1
UNION ALL
SELECT v2.*
FROM view2 v2
UNION ALL
SELECT v3.*
FROM view3 v3
我发现在新服务器上如果我只使用一个UNION ALL和两个视图,查询将在几秒钟内执行。例如,以下两个都将在10秒内成功执行。
SELECT v1.*
FROM view1 v1
UNION ALL
SELECT v2.*
FROM view2 v2
和
SELECT v2.*
FROM view2 v2
UNION ALL
SELECT v3.*
FROM view3 v3
但是,只要我将额外的UNION ALL添加到语句中以包含第三个视图,查询大约需要5分钟。
视图本身不是问题,因为在旧服务器上它运行得很好。新服务器上是否有一些我可能会丢失的设置可能会加快这一点?
提前致谢。
更新
我注意到这并不是因为使用UNION ALL组合了三个视图这一事实,实际上它归结为两个特定的视图,这些视图一起使用UNION ALL。解释:
SELECT v1.* FROM view1 v1
UNION ALL
SELECT v2.* FROM view2 v2
并且
SELECT v2.* FROM view2 v2
UNION ALL
SELECT v3.* FROM view3 v3
两者都在10秒内执行,但以下需要5分钟才能执行。
SELECT v1.* FROM view1 v1
UNION ALL
SELECT v3.* FROM view3 v3
这不是由于返回的行数,因为返回最多行(~3500行)的视图实际上是从慢速UNION ALL语句view2中省略的。其他两个视图每个返回大约400行。
这是数据的问题吗?在这两种观点中我应该寻找什么?
答案 0 :(得分:3)
评论太长了。
问题 - 很可能 - 不是union all
而是观点。视图是在第一次在查询中调用时编译的。如果基础数据发生变化,执行计划可能不会改变。
您应该比较两台服务器上的执行计划。然后,您应该在两台服务器上重新编译查询。
如果这样做,您可能希望设置一个每晚重新编译视图的作业,以确保执行计划与基础数据保持同步。
答案 1 :(得分:1)
SQL Server 2014有一个全新的基数估算器,这意味着您可能会获得与旧版本不同的执行计划。您可以尝试在查询结尾添加OPTION(QUERYTRACEON 9481)以强制使用旧版本的CE。
如果有帮助 - 这就是问题所在。如果没有 - 继续寻找(你可以发布执行计划吗?)
答案 2 :(得分:0)
我设法在大约15秒内完成了这个工作;速度快!
下面的链接记录了由于对返回的行数进行大幅高估而使用新的SQL Server 2014基数估算器运行某些复杂查询的速度要慢得多的问题。最后,解决方案是将跟踪标志4199添加到查询中,这解决了问题。
SELECT v1.*
FROM view1 v1
UNION ALL
SELECT v2.*
FROM view2 v2
UNION ALL
SELECT v3.*
FROM view3 v3
OPTION (QUERYTRACEON 4199)