2014-10-30 18 views
0

在SQL Server 2008 R2中,有沒有一種方法可以使用一些提示來強制執行這個查詢,該查詢在連接中使用OR,其運行速度與下面的代碼一樣快,它將UN替換爲OR。我可以在不使用聯合的情況下使用OR更快地進行聯接嗎?

慢查詢:

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

+0

你檢查了缺失的索引嗎?即審查了實際執行計劃? – 2014-10-30 20:33:43

+0

這兩個問題的答案都可以在原始文章中找到;然而,我並不是在尋找數據庫體系結構的建議,只是想讓SQL Server不採用愚蠢的方式來獲得結果而不使用聯合。 – John 2014-10-30 20:50:18

回答

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 
+0

我嘗試了三聯左連接,它的運行速度與聯盟的速度相同,但後來我加入了更多表格,所以很遺憾,這最終會比使用聯盟更醜。我會更新帖子,提及我隨後加入配料。 – John 2014-10-30 20:37:52

+0

無論如何,我無法看到這些左連接比UNION ALLs醜,發佈你的整個查詢,半個問題只會給你一半的答案。 – 2014-10-30 20:40:20

+0

也許使用三聯接,然後像'JOIN Recipe r ON COALESCE(i.RecipeID,i2.RecipeID,i3.RecipeID)= r.RecipeID'。這不是很好,但可能不像使用工會那樣醜陋。但是,可能會出現與原始加入相同的性能問題? – wolfgangwalther 2014-10-31 01:03:41

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)) 
這個簡化版本

但是,嘿,也許執行路徑會有所不同。

+1

值得一試!所以它沒有解決我的問題,但它在技術上使慢速版本更快一點......你是1%!我認爲我們需要讓SQL服務器進入非自願康復。執行計劃與慢版本 - http://imgur.com/eMzqPvL&zqQ6snz#0 – John 2014-10-30 21:07:48

相關問題