2014-09-24 63 views
-2

我有以下兩個實體:SQL - IN,JOIN或存在過濾

project(identifier, name, ...) 
member(identifier, name, ...) 

他們下表通過加入:

project-member(project_identifier, member_identifier) 

什麼是找出最常見的方式哪個項目的某個成員(通過標識符)屬於?我看到三種可能性:

select r1.* 
from project r1 
join project-member r2 
     on r2.member_identifier = 3 and r1.identifier = r2.project_identifier; 

select * 
from project r1 
where r1.identifier in (select project_identifier from project-member where member_identifier = 3); 

select * 
from project r1 
where exists (select * from project-member where member_identifier = 3 and project_identifier = r1.identifier); 

我明白,這主要取決於數據和查詢計劃應與現實生活中的數據進行分析,但我想知道默認的選擇會是什麼。我期望這是EXISTS建設,但我想徵求你的意見。

+0

重複http://stackoverflow.com/questions/13692992/join-versus-exists-performance,http://stackoverflow.com/questions/227037/can-i-get-better-performance-using-a加入或使用存在,http://stackoverflow.com/questions/1001543/in-vs-join-with-large-rowsets和許多其他 – LittleBobbyTables 2014-09-24 14:05:03

+0

每個人都有優點和缺點,以他們的使用。就我個人而言,我嘗試使用連接,因爲它似乎從來不會失敗,我需要從另一個表中獲取數據。表格在某些時候。如果我確實知道我不需要這些數據,那麼我通常會使用存在的。我通常默認爲IN,當我有一個已經定義的集合並且可以將它作爲變量傳遞時。但總有例外和背景通常很重要。我需要最佳性能,最簡單的維護還是可能擴展?所有3個都很常見。評估性能存在可能是最快的;假設適當的指標。但你要求COMMON,所以3 – xQbert 2014-09-24 14:21:02

回答

0

正如你所說,它取決於許多因素沒有在問題中說明,但假設有正確的索引,我相信它們會產生相同或至少非常相似的查詢計劃,因爲它們都是從獲取特定集合開始的來自項目成員的行,然後加入項目。

我覺得這個變體似乎最自然:

select p.* 
from project-member pm 
inner join project p on p.identifier = pm.project_identifier 
where pm.member_identifier = 3 

也就是說,從表中過濾行的基礎上你有一個謂語,然後加入其他表,讓你真正需要的信息。