MySQL更新与subselect太慢

时间:2011-06-02 13:56:58

标签: mysql performance greatest-n-per-group sql-update

更新查询出现问题的时间超过20分钟(之后我将其删除)。

情景:

表一有300K记录。

表2包含相同的记录集(复制过),但有一个额外的字段需要包含与多个字段匹配的记录的id,并且具有另一个(分数)的最高值。为了澄清,最终结果应该是包含300K记录的表2,每条记录具有另一条具有相同基本属性集的记录的id,以及具有这些属性的记录集中的最高分。

当我只将2K记录而不是完整的300k记录复制到表2中时,以下内容在~5s内完成。

UPDATE vtable2 v1 SET v1.buddy = (
    SELECT v2.id FROM vtable1 v2
    WHERE
    v2.group_id = v1.group_id AND
    // 6 more basic comparisons
    ORDER BY score DESC LIMIT 1
)

我需要找到完整300K记录的好友。参与加入和排序的所有字段都有索引。

非常感谢。

3 个答案:

答案 0 :(得分:1)

MySQL子查询往往会慢一些。在这种情况下,我更喜欢使用连接。我对你的架构设计并不十分清楚 - 但是你可以试试这样的东西 -

UPDATE vtable2 v1
[INNER] JOIN vtable1 v2 
ON v2.group_id = v1.group_id
AND //OTHER JOIN CONDITIONS IF ANY
WHERE
//any other conditions
SET
v1.buddy = v2.id

PS - 当然,您需要确保列上有适当的索引。如果您需要帮助,可以使用解释计划发布整个查询。

答案 1 :(得分:0)

您可以使用数字变量

进行测试
 SELECT v2.id FROM vtable1 v2
WHERE
v2.group_id = 1 AND
// 6 more basic comparisons
ORDER BY score DESC LIMIT 1

无论如何,我认为使用加入它更好,但我没有架构DB 也许你的SQL数据库索引有问题。

答案 2 :(得分:0)

您可以使用排除连接查找vtable1中的行,以便找不到vtable1中具有更高分数的其他行。

UPDATE vtable2 AS v1
INNER JOIN vtable1 AS v2a ON v1.group_id = v2a.group_id AND (...conditions...)
LEFT OUTER JOIN vtable1 AS v2b ON v1.group_id = v2b.group_id
  AND v2a.score < v2b.score AND (...conditions...)
SET v1.buddy = v2.id
WHERE v2b.group_id IS NULL;

您必须复制外连接的表达式中的所有其他条件;你不能把它们放到WHERE子句中。