2010-03-19 32 views
5

嗨,我有以下表T:替代「其中山坳中(列表)」爲MySQL

id 1 2 3 4 
col a b a c 

我想要做一個選擇,返回ID,山坳時(COL),具有計數組(COL)>做它的1

的一種方式是

SELECT id,col FROM T 
    WHERE col IN (SELECT col FROM T GROUP BY(col) HAVING COUNT(col)>1); 

實習生選擇(從右側)返回 'a' 和主一個(左)將返回參考圖1,和圖3,

問題在於where語句似乎非常緩慢。在我的真實情況下,內部選擇的結果有很多'col',大約有70000個,它需要幾個小時。

現在,執行內部選擇和主要選擇獲取所有ID和UPCS並在本地執行交集要快得多。 MySQL應該能夠有效地處理這種查詢。

我可以用什麼來替代哪裏進行連接或更快?

感謝

回答

5

你可以嘗試,如果使用INNER JOIN速度東西

  • 確保您有col
  • 指數上col, id覆蓋索引可能獲得你甚至更好的性能

SQL語句

SELECT T.id, T.col 
FROM T 
     INNER JOIN (
      SELECT col 
      FROM  T 
      GROUP BY col 
      HAVING COUNT(*) > 1 
     ) tcol ON tcol.col = T.col 
+0

謝謝。這工作得很好。我在tcol之前插入關鍵字'as'。我甚至沒有col的索引,但它工作得非常快。 – duduklein 2010-03-19 14:00:48

2
SELECT id, col 
FROM t t1 
WHERE EXISTS 
     (
     SELECT NULL 
     FROM t t2 
     WHERE t2.col = t1.col 
       AND t2.id <> t1.id 
     ) 

確保您有(col)(在InnoDB)或(col, id)指數(以MyISAM

內部查詢將停止儘快評估,因爲它找到了第一個匹配值。使用索引,這將在單索引查找最多兩次索引掃描後發生。

+0

+1。也許你可以添加一些解釋*爲什麼*這比OP或我的解決方案快得多*。我認爲這與無需掃描整個索引並在發現匹配時能夠停止有關。 – 2010-03-19 13:45:06