如果不使用联合,我可以使用OR更快地进行此JOIN吗?

时间:2014-10-30 20:22:12

标签: sql sql-server sql-server-2008-r2

在SQL Server 2008 R2中,是否有一种方法可以使用一些提示来强制此查询(在连接中使用OR)以低于下一个的速度运行,这会将UN替换为Unions?

查询缓慢:

select <stuff> from 
UPCs u
JOIN Ingredients i on 
(u.UPCID = i.UPCID) or ( u.CategoryID = i.CategoryID and u.Quality = i.Quality) or     (u.ManufacturerID = i.ManufacturerID and u.Quality = i.Quality)

更快的查询执行相同的操作,但单独应用条件并将结果与​​联合连接:

select <stuff> from UPCs u join Ingredients i on 
(u.UPCID = i.UPCID)
UNION ALL
select <stuff> from UPCs u join Ingredients i on u.CategoryID = i.CategoryID and u.Quality =     i.Quality)
UNION ALL 
select <stuff> from UPCs u join Ingredients i on u.ManufacturerID = i.ManufacturerID and u.Quality = i.Quality

使用联盟,它在UPC上进行循环连接,并进行2次散列连接,然后将联合的结果连接在一起。 UPC ID是一个聚簇主键,其他字段是非索引的,两个表都非常大。

编辑:请注意,我后来加入了成分,所以我很乐意将其分解为成分的多个连接,但前提是它比联盟更快。真实世界的查询是这样的:

Select <stuff> from #UnknownPoursForThisEvent up
JOIN UPCs u on up.UPCID = u.UPCID
JOIN Tags t on t.TagNumber = up.TagNumber
JOIN Ingredients i on (i.UPCID = u.UPCID) or ( u.CategoryID = i.CategoryID and u.Quality =     i.Quality) or (u.ManufacturerID = i.ManufacturerID and u.Quality = i.Quality)
join Recipe r on i.RecipeID = r.RecipeID
join TicketItemAliases tia on tia.RecipeID = tia.RecipeID
<... Join, left join, and apply lots of other criteria>

EDIT2:执行计划。 http://imgur.com/eMzqPvL&zqQ6snz#1

2 个答案:

答案 0 :(得分:0)

不确定这是否有帮助,但值得一试......

SELECT <stuff> 
FROM       UPCs        u 
INNER JOIN Ingredients i  ON  i.UPCID = u.UPCID
LEFT  JOIN Ingredients i2 ON  u.CategoryID = i2.CategoryID 
                          AND u.Quality = i2.Quality
LEFT  JOIN Ingredients i3 ON  u.ManufacturerID = i3.ManufacturerID 
                          AND u.Quality = i3.Quality

答案 1 :(得分:0)

逻辑

select <stuff> from 
UPCs u
  JOIN Ingredients i on 
       (u.UPCID = i.UPCID) or 
       (u.CategoryID = i.CategoryID and u.Quality = i.Quality) or
       (u.ManufacturerID = i.ManufacturerID and u.Quality = i.Quality)

应该与

的简化版本相同
select <stuff> from 
UPCs u
  JOIN Ingredients i on 
       u.UPCID = i.UPCID or 
       (u.Quality = i.Quality And
       (u.CategoryID = i.CategoryID Or u.ManufacturerID = i.ManufacturerID))

但是,执行路径可能会有所不同。