2009-05-26 90 views
1

我想以最有效的方式從一個表中選擇與另一個表中的「一個或多個」行匹配的所有行。在另一個表中快速選擇具有「1個或多個」匹配行的所有行

SELECT identity.id FROM identity 
INNER JOIN task ON 
    task.identityid=identity.id 
    AND task.groupid IN (78, 122, 345, 12, 234, 778, 233, 123, 33) 

目前,如果有多個匹配任務,這將返回相同的身份多次(但消除這些後來的性能損失不算太差)。我希望這樣做只能爲每個標識返回一行,與一個或多個這些任務組相匹配,我想知道是否有比DISTINCT或GROUP BY更有效的方法。

執行DISTINCT或GROUP BY的麻煩在於任務表仍然針對所有groupid匹配進行掃描,然後通過臨時表(有時使用filesort)將其縮減爲一個。我寧願它做一些短路評估 - 不要追求任何後續的任何匹配相同的身份後,找到一個。

我想做一個EXISTS子查詢,但我不知道這些如何優化。我需要它在身份表之前首先加入任務表,所以我沒有對身份表進行全面掃描,這個身份表非常大,並且會有很多不匹配。

+0

您可以通過提供(groupid,identityid)上的索引來優化任務表掃描 - 給予我在MySQL中的WHERE EXISTS或其他子查詢的性能經驗,這似乎是一種更有前途的方法(如果子查詢的優化在6.0中被徹底改變了,有人讓我知道了,請打開泡泡! - ) – 2009-05-26 02:22:39

+0

是的,我的任務表上的PRIMARY就像那樣(每個任務的每個任務組有一個任務),所以它非常高效。 – thomasrutter 2009-05-26 13:04:53

回答

1

只要使用「SELECT DISTINCT」與你所擁有的應該是有效的MySQL。您可能需要將您的值放在表中並加入,而不是使用「IN(...)」。

+0

當我使用'DISTINCT'時,它顯示'使用臨時表'。對於我的簡化測試,它仍然看起來相當快,但是這不會增加可以趕上我的相當多的開銷嗎?是DISTINCT的快速/內存臨時表? – thomasrutter 2009-05-26 02:17:14

0

MYSQL是否支持TOP N語法?如果是這樣的話:

SELECT TOP 1 identity.id FROM identity 
INNER JOIN task ON 
    task.identityid=identity.id 
    AND task.groupid IN (78, 122, 345, 12, 234, 778, 233, 123, 33) 
+0

mysql語法(而不是在SELECT之後的TOP 1)將在查詢的末尾添加ORDER BY identity.id DESC LIMIT 1 - 但是TOP或LIMIT產生的單行答案似乎與問題請求。 – 2009-05-26 02:19:28

0

只要你在子查詢中比較的列被索引,存在就應該適合你。

我認爲這個存在的性能會比連接和分組的性能​​好一點,但我必須試一試才能確定。我已經在MySQL中運行了足夠的性能,但是我的預測錯誤,因此知道值得一試。

相關問題