2008-09-22 145 views
11

我有兩個包含任務和註釋的表格,並且想要檢索每個任務的相關注釋數量的任務列表。這兩個查詢做的工作:Transact-SQL - 子查詢或左連接?

select t.TaskId, 
     (select count(n.TaskNoteId) from TaskNote n where n.TaskId = t.TaskId) 'Notes' 
from Task t 

-- or 
select t.TaskId, 
     count(n.TaskNoteId) 'Notes' 
from Task t 
left join 
     TaskNote n 
on  t.TaskId = n.TaskId 
group by t.TaskId

他們之間有一個區別,我應該使用了另一種,或者是他們做同樣的工作的只有兩個方法呢?謝謝。

回答

12

在小數據集他們洗,當涉及到性能。當索引時,LOJ會好一點。

我對大數據集是一個內部聯接中(內部聯接將工作太)將通過一個非常大的因素(對不起,沒有數字)跑贏子查詢。

+0

同上內部連接 ​​- 我已經看到這對大集合有很大的影響(假設這是你想要的正確行爲,並且你可能需要使用ISNULL()或類似的函數) – 2008-09-22 22:31:01

0

您可以使用任意一種,並且它們在語義上是相同的。一般來說,經驗法則是使用哪種形式更容易閱讀,除非性能是一個問題。

如果性能是一個問題,然後使用其他形式的重寫查詢實驗。有時優化器將使用一個索引而不是另一個索引。

1

對此沒有明確的答案。您應該查看SQL計劃。就關係代數而言,它們本質上是等價的。

6

在大多數情況下,優化器會將它們視爲相同。

我傾向於選擇第二個,因爲它有較少的嵌套,這使得它更易於閱讀和更易於維護。出於同樣的原因,我開始使用SQL Server的公用表表達式來減少嵌套。

此外,第二語法是更靈活的,如果有進一步的聚集體,其可能會在將來,除了被加入到COUNT,像MIN(some_scalar),MAX(),AVG()等等

2

如果您正在使用SQL Server Management Studio,可以將兩個版本都輸入到查詢編輯器中,然後右鍵單擊並選擇顯示預計執行計劃。它會給你兩個相對於該批次的百分比成本。如果他們預計會採取同樣的時間,他們都會顯示爲50% - 在這種情況下,由於其他原因(更易於閱讀,更容易維護,更符合您的編碼標準等)選擇您喜歡的。否則,您可以選擇相對於該批次具有較低百分比成本的那個。

您可以用同樣的方法來看待改變任何查詢,通過比較兩個版本的做同樣的事情來提高性能。

當然,因爲它是相對於該批次成本,這並不意味着,要麼查詢一樣快,因爲它可能是 - 它只是告訴你他們如何互相比較,而不是一些名義上的最佳查詢得到相同的結果。

5

因爲它是被用於在外部查詢的每一行執行的子查詢速度會變慢。連接一次會更快。我相信查詢優化器不會重寫這個查詢計劃,因爲它無法識別等價。

通常情況下,您會爲這種計數做一個連接和分組。如果他們必須在沒有參與另一個連接的表上執行一些分組或更復雜的謂詞,則顯示的排序的相關子查詢主要是感興趣的。

1

我在任何可能的地方避免子查詢。聯合通常會更有效率。