2009-11-12 34 views
1

我正在優化其中一個SQL作業。SQL查詢性能'<>'運營商vs不存在

在這裏,我有幾個地方,我們已經使用<>運算符。同樣的查詢可以使用NOT EXISTS運算符來替換。我只是想知道哪種方法更好。

示例查詢

If(@Email <> (select Email from Members WHERE MemberId = @MemberId)) 
--Do Something. 

--Same thing can be written as 
If(NOT EXISTS (SELECT Email FROM Members WHERE MemberId = @MemberId AND Email = @EmailId)) 

哪個更好?

我經歷了兩個執行計劃(coundn't附加,因爲所有圖像託管被阻止在辦公室)。 我可以看到<>運算符具有Assert和Stream Aggregate操作而非NOT EXISTS。不知道它們是好還是壞還是沒有影響。

回答

3

不存在通常更好(雖然在你的情況下,如果表格很小和/或正確索引它可能不是這種情況)。

差不多對於您試圖查明某個記錄是否存在(或不存在)的查詢,您總是應該使用EXISTS/NOT EXISTS!

背後的推理是EXISTS(和NOT EXISTS)查詢將在條件滿足時立即停止(或者在NOT EXISTS被證明爲false的情況下),而不是使用子查詢,這將繼續掃描記錄整桌子。

+0

上面的子查詢只給出一個結果。那麼應該有什麼區別? – 2009-11-12 17:20:09

+0

猜猜它應該在這裏相同。雖然我仍然懷疑在執行計劃中出現了兩個額外的實體(Assert和Stream Aggregate)。我必須對此做更多的研究。謝謝。 – 2009-11-12 18:20:06

1

兩個語句之間的區別在於「在純SQL中完成了多少操作,以及運行該過程/腳本等的引擎完成了多少操作(我想說的是數據庫以及數據庫外的內容,但是在存儲過程中,這兩個部分都由數據庫處理。)

在您的示例中,第一條語句使用SQL來獲取一個成員的Email.Table訪問使用我假設的主關鍵字及其關聯的唯一索引,因此即使對於大型表格,它也應該是非常快的。電子郵件傳遞到SQL以外,然後在腳本中進行比較。

在第二個語句中,漂亮發生同樣的事情。 MemberID再次用於訪問唯一記錄,然後比較電子郵件並將布爾結果傳回SQL之外。

因此,您的示例的性能應該非常相似。

當需要將多個值傳遞到SQL之外並且需要完成更復雜的比較時(例如MikyD注意到),會有不同的考慮(例如,使用SQL選擇大量電子郵件,然後在腳本中與Email IN (Select ..)之類的東西進行比較)。那麼通常最好在SQL中儘可能多地做好工作,在SQL和非SQL之間傳輸最少量的數據,並讓數據庫找出最有效的方式來獲取數據。

+0

謝謝IronGoofy! – 2009-11-12 17:34:16