与具有相同结果的硬编码值相比,sql嵌套语句的速度非常慢



很抱歉我不能在这里发布有问题的实际视图,可以说有25个联接和大约200个字段——这太可怕了——但我希望一个如何调用视图的例子足以让人们了解我的问题。

如果我运行以下语句:

select top 100 personId 
from vw_GetPeople 
where personFirstname = 'John'

我在不到一秒钟的时间里就得到了100个身份证的列表。

如果我把那100个身份证硬编码成这样的声明

select * 
from vw_AllPersonAssociatedGarbage 
where personId in ( <<my 100 comma-separated id's here>> )

然后视图会在几秒钟内返回结果。

如果我嵌套第一个语句,尝试这样使用它:

select * 
from vw_AllPersonAssociatedGarbage 
where personId in (select top 100 personId from vw_GetPeople 
where personFirstname = 'John')

然后这个陈述大约需要一分钟才能完成。

为什么嵌套语句不简单地等同于";harcoded";personId列表语句?

select top 100 personId from vw_GetPeople where personFirstname = 'John' 

在几秒钟内返回是吗?尝试将该结果集插入临时表或表变量中,并将该临时表放置在子查询中。临时表或表变量将小于您的视图。

select * from vw_AllPersonAssociatedGarbage where personId in
( SELECT personID FROM #persons )
select * from vw_AllPersonAssociatedGarbage where personId in
( SELECT personID FROM @persons )

它很可能会重新运行,为vw_AllPersonAssociatedGarbage中的每个记录选择前100名,如果有大量数据,这可能会很昂贵。

为什么嵌套语句不简单地等同于"harcoded";personId列表语句?

在SQL Server中,视图基本上是作为代码插入到查询中,然后在整个语句的上下文中进行编译。这意味着视图的执行计划可能会因使用方式而异。这可能是你所看到的现象,但尚不清楚是一种观点还是两种观点都受到了影响。

您可以尝试使用join代替:

select apag.* 
from vw_AllPersonAssociatedGarbage apag join
(select top 100 personId
from vw_GetPeople 
where personFirstname = 'John'
) p
on p.personId = apag.personId;

IN实际上是一个更复杂的操作,因为join可以返回重复的行。

如果所有其他操作都失败,则可以为视图使用临时表或表变量。但是,如果视图被广泛使用,您可能真的想要一个索引视图,它具体化了底层数据,应该有利于所有查询。

最新更新