2010-06-30 91 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;