问题
In SQL Server 2008 R2, is there a way to use some hints to force this query, which uses OR in a join, to run as fast as the below one, which replaces the OR with Unions?
Slow query:
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)
Faster query doing the same thing, but applying the criteria separately and concatenating the results with unions:
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
With the unions, it's doing a loop join on UPCs, and 2 hash joins, then concatenating the results of the union together. UPC ID is a clustered primary key, the other fields are non-indexed, and both tables are very large.
EDIT: Please note, I'm doing subsequent joins off of ingredients, so I'd happily break it up into multiple joins on ingredient, but only if it's even faster than the union. Real world query is something like this:
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: Execution plans. http://imgur.com/eMzqPvL&zqQ6snz#1
回答1:
Not sure if this will help but worth giving it a go.....
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
回答2:
logically
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)
Should be the same as this simplified version of
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))
but hey maybe the execution path will be different.
来源:https://stackoverflow.com/questions/26662555/can-i-make-this-join-using-or-faster-without-using-unions