The*_*war 17 performance sql-server sql-server-2012 exists query-performance
我有以下查询:
select databasename
from somedb.dbo.bigtable l where databasename ='someval' and source <>'kt'
and not exists(select 1 from dbo.smalltable c where c.source=l.source)
Run Code Online (Sandbox Code Playgroud)
上述查询在三秒内完成。
如果上面的查询返回任何值,我们希望存储过程退出,因此我将其重写如下:
If Exists(
select databasename
from somedb.dbo.bigtable l where databasename ='someval' and source <>'kt'
and not exists(select 1 from dbo.smalltable c where c.source=l.source)
)
Begin
Raiserror('Source missing',16,1)
Return
End
Run Code Online (Sandbox Code Playgroud)
但是,这需要 10 分钟。
我可以像下面这样重写上面的查询,它也可以在不到 3 秒的时间内完成:
select databasename
from somedb.dbo.bigtable l where databasename ='someval' and source <>'kt'
and not exists(select 1 from dbo.smalltable c where c.source=l.source
if @@rowcount >0
Begin
Raiserror('Source missing',16,1)
Return
End
Run Code Online (Sandbox Code Playgroud)
上面重写的问题是上面的查询是更大的存储过程的一部分,它返回多个结果集。在 C# 中,我们遍历每个结果集并进行一些处理。
上面返回一个空的结果集,所以如果我采用这种方法,我必须更改我的 C# 并再次进行部署。
所以我的问题是,
为什么使用 just
IF EXISTS更改计划要花费这么多时间?
以下是可能对您有所帮助的详细信息,如果您需要任何详细信息,请告诉我:
快速执行计划
注意:两个查询是相同的(使用参数),唯一的区别是EXISTS(虽然我在匿名时可能犯了一些错误)。
表创建脚本如下:
http://pastebin.com/CgSHeqXc -- 小桌统计
http://pastebin.com/GUu9KfpS -- 大桌统计
Tom*_*m V 19
如已经由保罗·怀特:在他的博客里面的优化:行目标在深度的EXISTS介绍一排目标,即喜欢NESTED LOOPS或MERGE JOIN以上HASH MATCH
作为最后一个示例,请考虑逻辑半连接(例如使用 EXISTS 引入的子查询)共享整个主题:应该对其进行优化以快速找到第一个匹配行。
在您的查询中,这显然会引入嵌套循环并删除并行性,从而导致计划变慢。
因此,您可能需要找到一种无需使用NOT EXISTSfrom查询即可重写查询的方法。
您可能会使用 a 重写查询LEFT OUTER JOIN并通过测试来检查 smalltable 中没有行NULL
If EXISTS(
SELECT databasename
FROM somedb.dbo.bigtable l
LEFT JOIN dbo.smalltable c ON c.source = l.source
WHERE databasename = 'someval'
AND source <> 'kt'
AND c.source IS NULL
)
Run Code Online (Sandbox Code Playgroud)
您也可以使用EXCEPT查询,具体取决于您需要比较的字段数量,如下所示:
If EXISTS(
SELECT source
FROM somedb.dbo.bigtable l
WHERE databasename = 'someval'
AND source <> 'kt'
EXCEPT
SELECT source
FROM dbo.smalltable
)
Run Code Online (Sandbox Code Playgroud)
请注意,Aaron Bertrand有一篇博客文章提供了他更喜欢 NOT EXISTS 的原因,您应该通读该文章以查看其他方法是否更有效,并注意在 NULL 值的情况下潜在的正确性问题。
相关问答:IF EXISTS 比嵌入式 select 语句花费的时间更长
| 归档时间: |
|
| 查看次数: |
8864 次 |
| 最近记录: |