我正在研究一个名为AcmeView
的视图附带的MS SQL 2008数据库。当我编写AcmeView
脚本时,我发现它将其他三个视图连接在一起:View1
,View2
和View3
。一位同事问我是否可以撰写一个视图,将AcmeView
的内容与另一个视图中的数据结合起来:NewView
。
AcmeView
在三秒内返回结果集;它的组成视图每行包含数万行。
NewView
是一个小得多的观点;它每个只返回大约两千行;它会在很短的一秒钟内返回结果集。
因此,当我使用AcmeView
将NewView
修改为INNER JOIN时,我感到很失望,生成的视图需要将近20秒才能返回其结果集。这个观点可能有什么问题让它变得如此之慢?
AcmeView
的SELECT语句如下所示:
SELECT *
FROM
View1
INNER JOIN View2
ON View2.foo = View1.foo
INNER JOIN View3
ON View3.bar = View2.bar
-- Executes in 3 seconds
SELECT *
FROM
View1
INNER JOIN View2
ON View2.foo = View1.foo
INNER JOIN View3
ON View3.bar = View2.bar
INNER JOIN NewView
ON NewView.qwerty = View1.querty
-- Executes in 20 seconds; why so long?
如何在我的FROM子句中再添加一个视图NewView
会减慢查询速度,以及我该怎么办?可以在一小段时间内再次查询NewView
。
答案 0 :(得分:0)
一个JOIN并不难产生那么大的差异。
如果连接键没有以相同的方式排序 - 很可能因为其中一个“表”是一组连接的结果 - 它将全部重新排序或者只是在一个大的嵌套循环中完成。 / p>
正如@magnus所说,如果你拉出两者的执行计划,你可能会很容易看到添加的内容。
而且我猜它是一个嵌套循环,对于一个表中的每一行,它扫描另一行中的每一行。
如果您认为执行计划对您而言是新的,请查看这篇高度评价的帖子:
How to read an execution plan in SQL Server