为什么使用过滤表的内连接比没有过滤的内连接更慢?

3

SQL服务器 2008 在 Windows 2008 上

请比较以下 SQL:

1.

select count(*) 
from Trades t 
inner join UserAccount ua on ua.AccID = t.AccID

2.

select count(*) 
from Trades t 
inner join (
    select * 
    from UserAccount ua 
    where ua.UserID = 1126
) as theua on theua.AccID = t.AccID

3.

select count(*) 
from Trades t 
inner join UserAccount ua on ua.AccID = t.AccID 
where ua.UserID=1126

给定的Trades表有数百万行,而UserAccount表非常小。AccID可能会重复。
执行结果:
1. 234734792 2. 8806144 3. 8806144
我希望第二个查询至少和第一个一样快,但实际上它比第三个查询慢得多。 时间消耗:
1. 2秒 2. 10秒 3. 8秒
有人能解释原因吗?当我需要像UserID = 1126这样的过滤器时,是否可能使其更快?
1个回答

3
  1. 由于其条件最少,因此是最快的查询。(缺失的UserID)

  2. 由于它有一个内部查询,每个连接都必须执行,所以速度最慢。(顺便说一句:千万不要这样做)

  3. 由于额外的where条件(UserID),速度比#1慢。这是您要使用的查询。(您还可以将“where”替换为直接在连接后的“and”)

您是否设置了外键

还要确保您具有适当的索引(例如:AccID和UserID)。

从SSMS运行带有执行计划的查询,它会显示查询/索引中的潜在低效性。

在执行计划中,您应该注意表扫描等问题。您想要看到的是搜索


关于第二个问题,我能否将其选择到一个临时表中,然后与该临时表进行内部连接,这样会更快吗? - Rob Lao
你想要查询语句#3,那是最好的一个,但你可能缺少索引,这将会影响速度。 - Timeout
我在UserAccount表中的UserID和AccID上建立了索引,但在Trades表中没有。 - Rob Lao
你有外键吗?你检查了执行计划吗? - Timeout
@MrMoose,是的,您说得对,使用t.AccID索引可以极大地提高2和3的性能。 - Rob Lao
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接