2010-06-30 93 views
3

我有一個MySQL更新查詢需要很長時間才能完成。我錯過了一個更簡單的方法來實現相同的結果嗎?MySQL更新查詢與永久採取子查詢

"UPDATE table2, table1 
SET table2.id_occurrences = (SELECT SUM(IF(id = table2.id, 1, 0)) FROM table1) 
WHERE table2.id = table1.id;" 
  • table2包含id所有可能的值,每個一個記錄。
  • table1包含一些值id,但有一些值的多個記錄。
  • 我需要更新table2中的記錄以顯示table1中相應值id的出現次數。上面的查詢完成了這項工作,但是當table1包含500條記錄和table2 30,000條記錄時大約需要3分鐘。我有更大的表處理,所以這是太長了:)

在此先感謝。

回答

2

避免子查詢,使用聯接:

UPDATE table2 
LEFT JOIN table1 ON (table2.id = table1.id) 
SET table2.id_occurrences = COUNT(table1.id) 
GROUP BY table2.id 

哦,UPDATE不支持GROUP BY。試試這個查詢:

UPDATE table2 
LEFT JOIN (
    SELECT id, COUNT(*) AS cnt FROM table1 GROUP BY id 
) AS t1 
ON (table2.id = t1.id) 
SET table2.id_occurrences = t1.cnt 
+0

謝謝。是否有避免子查詢的特殊原因? 我很希望看到這種方法和Brian's/Jonathan's之間的速度差異,它將查詢時間從150s降低到20s,但是我得到以下語法錯誤: '#1064 - 您有你的SQL語法錯誤;請檢查與您的MySQL服務器版本對應的手冊,以便在第4行'GROUP BY table2.id'附近使用正確的語法。 – edanfalls 2010-06-30 09:07:14

+0

WHERE中的從屬子查詢針對主查詢的每一行執行,這可能會導致一個相當大的數字的額外查詢。最好將查詢重寫爲JOIN。我編造了這個查詢,看起來像UPDATE不支持GROUP BY。所以我會很快給你一個JOINed子查詢的查詢。加入的子查詢只執行一次。 – Naktibalda 2010-06-30 09:18:29

+0

這個查詢的執行時間是什麼? – Naktibalda 2010-06-30 10:12:00

5

我覺得你參加的更新或許沒有必要...

UPDATE table2 
    SET table2.id_occurrences = (SELECT COUNT(*) FROM table1 
            WHERE table2.id = table1.id); 
+1

的確。並確保你在每個表的id列上都有索引。 – 2010-06-30 08:45:10

+0

啊,是的,這是更快。我現在看到,我甚至不更新table1。非常感謝。 – edanfalls 2010-06-30 08:52:10

1

我會去這樣的事情:

UPDATE table2 
SET id_occurrences = (SELECT count(*) FROM table1 
         WHERE table1.id = table2.id) 
+0

如果我也能接受這個答案,我會的。感謝您的幫助,Brian剛剛到達那裏:) – edanfalls 2010-06-30 09:03:55

+0

他確實!和幾乎相同的代碼。他們說,偉大的思想家都會這樣想。 ;) – Jonathan 2010-07-01 07:35:06

0
UPDATE table2, table1 
SET table2.id_occurrences = (SELECT SUM(IF(id = table2.id, 1, 0)) FROM table1) 
WHERE table2.id in (select distinct table1.id from table1) AND table2.id = table1.id;