2011-09-23 36 views
2

我有兩個表與多對一的關係,我將調用Parent_Table和Child_Table(即一個父母有零個或多個孩子,但孩子只有一個父母) 。我需要計算至少有一個孩子滿足某些條件的父母的人數。哪個查詢是最佳的?爲多對一的關係優化SQL查詢

選項1(非常肯定它不是這一個)

SELECT COUNT(DISTINCT(pt.ID)) 
FROM PARENT_TABLE pt 
JOIN CHILD_TABLE ct 
ON pt.ID = ct.PARENT_ID 
WHERE <parent meets some condition> 
AND <child meets some condition> 

選項2

SELECT COUNT(pt.ID) 
FROM PARENT_TABLE pt 
WHERE pt.ID in 
(
SELECT ct.PARENT_ID 
FROM CHILD_TABLE ct 
WHERE <child meets condition> 
) 
AND <parent meets some condition> 

選項3(我的猜測是最快)

SELECT COUNT(pt.ID) 
FROM PARENT_TABLE pt 
WHERE EXISTS 
(
SELECT 1 
FROM CHILD_TABLE ct 
WHERE ct.PARENT_ID = pt.ID 
AND <child meets condition> 
) 
AND <parent meets some condition> 

或者是它的東西其他完全?它取決於每個表的大小,或者這兩個條件的複雜程度,或者數據是否被排序?

編輯:數據庫是Oracle。

+1

爲什麼不對一些適當大小的樣本數據做一些性能測試? –

+0

在SQL Server 2005或更高版本中,選項2和3將被處理相同。 – JNK

+0

爲了得到準確的答案,請分享你的RDBMS。 – JNK

回答

3

第一個查詢很慢,其他人應該在大多數數據庫上快速運行。

如果不知道DB很難多說:

但是:COUNT(*)往往更快比count(names_field)永不慢
計數(不同(遠處))是慢

或者是完全不同的東西?

這取決於數據庫和數據庫的確切版本。

是否依賴於每個表

是的,起着很大一部分

或兩個條件

可能

複雜的大小

或數據是否被排序?

如果您想快速選擇,則所有用於連接的字段都必須建立索引。
而where子句中使用的所有字段必須是索引或低基數。

+0

+1 - 這幾乎可以用給出的有限信息進行總結。 – JNK

+0

count(*)的語義也不同於count(columnname) – EvilTeach

+0

@EvilTeach,不在內部聯接的上下文中的主鍵上。 – Johan

0

對我來說,第一個看起來是最好的,因爲它是最簡單的閱讀,但顯然不能回答你的問題。

你真的必須做的是爲每個查詢生成執行計劃並分析它們(我認爲大多數流行的DBMS都有一個工具可以做到這一點)。它會爲您提供每個查詢的成本值。

如果你不能這樣做,我想你可以運行一堆查詢並比較執行時間。

還是完全是別的嗎?它取決於每個表的大小,或者這兩個條件的複雜程度,或者數據是否被排序?

所有這一切以及更多。

-1

就像評論者所說,回答這個問題的最好方法是運行查詢和度量。但是,一般來說,數據庫引擎會非常有效地優化連接 - 我敢肯定,在3個查詢中幾乎沒有區別,查詢優化器完全有可能將它們全部轉換爲相同的基本查詢(2和3是相同的)。

到目前爲止對查詢的最大影響將是「孩子滿足某些條件」和「父母滿足某些條件」子句。我專注於優化這一點。

+0

不正確。 「IN」與「DISTINCT」對處理時間有很大的影響。 – JNK

+0

啊是的 - DISTINCT通常是邪惡的,特別是。從性能角度來看。沒有發現那個小塊頭......但是,我認爲where子句會產生很大的影響 –