SQL查询效率——UNION ALL的影响
Posted
技术标签:
【中文标题】SQL查询效率——UNION ALL的影响【英文标题】:SQL query efficiency - impact of UNION ALL 【发布时间】:2013-04-14 15:13:03 【问题描述】:我最近写了一个有这部分的存储过程
select T.Id from Teams T
inner join
(
select SG.Team1Id, SG.Team2Id from SG
union all
select SP.Team1Id, SP.Team2Id from SP
) G
on T.Id in (G.Team1Id, G.Team2Id)
我怀疑这个查询效率
此查询是否会从子查询中的SG
和SP
中获取所有记录,然后应用连接条件?如果是,那么我认为这不是有效的
或
Sql server 足够聪明,只能从两个表中获取符合连接条件的行?
【问题讨论】:
发布查询计划,以便我们了解引擎将如何执行此查询。on T.Id in (G.Team1Id, G.Team2Id)
意味着您将始终获得嵌套循环连接。它是T.Id = G.Team1Id or T.Id = G.Team2Id
。见Is having an 'OR' in an INNER JOIN condition a bad idea?
【参考方案1】:
派生表中的UNION ALL
可能比
SELECT T.Id
FROM Teams T
INNER JOIN SG
ON T.Id IN ( SG.Team1Id, SG.Team2Id )
UNION ALL
SELECT T.Id
FROM Teams T
INNER JOIN SP
ON T.Id IN ( SP.Team1Id, SP.Team2Id )
因为您问题中的版本只需要通过Teams
。如果表SP
和SG
具有约束使得Team1Id
不能与Team2Id
相同并且单独的列被索引,那么以下可能会执行得更好(对于某些数据分布,特别是如果Teams
相对与所涉及的其他表相比大)
SELECT T.Id
FROM Teams T
INNER JOIN (SELECT SG.Team1Id
FROM SG
UNION ALL
SELECT SG.Team2Id
FROM SG
UNION ALL
SELECT SP.Team1Id
FROM SP
UNION ALL
SELECT SP.Team2Id
FROM SP) G(TeamId)
ON T.Id = G.TeamId
【讨论】:
此外,优化器可以从 2 变为 1,但不能从 1 变为 2。这是 2012 年的不幸限制。以上是关于SQL查询效率——UNION ALL的影响的主要内容,如果未能解决你的问题,请参考以下文章
sql中,只使用union和先union all再distinct,两种方式哪个效率高?