对UPDATE重复行的MySql查询非常慢。建议需要加快

时间:2016-08-28 21:09:02

标签: mysql performance sql-update

我的表promotional包含列(promoidmobilemessage_sent_status和另外15列...)。 该表有大约10万行。我想将列的值(mobile)更新为空白(empty string),除第一次出现外,其中包含重复的条目。

UPDATE promotional
SET mobile='', message_sent_status='BLANK'
WHERE mobile!='' and promo_id not in
                 (
                   SELECT min(promo_id)
                   FROM (SELECT * FROM promotional) as temp
                   GROUP BY mobile
                 );

此查询工作正常,但即使没有找到重复的条目,也需要花费大量时间(大约1分钟)。

但是当我改变这条线时

FROM (SELECT * FROM promotional) as temp

// with only required column
FROM (SELECT promo_id, mobile,messsage_sent_status, FROM promotional) as temp

大约需要40秒。

我想知道如果有任何方法可以加快查询速度,或者查询所花费的时间是可以接受的。

2 个答案:

答案 0 :(得分:3)

您的SQL更新不正确,因为您的问题是每个移动设备保持每个最小值

不确定您的表格密钥,如果您在移动设备上有索引密钥,它会加快速度:

alter table promotional add key (mobile)

然后运行:

UPDATE promotional AS a
JOIN   promotional AS b
ON  a.mobile = b.mobile
AND a.promoid < b.promoid
AND a.mobile != ''
SET b.message_sent_status = ''

我的测试表有33840行,上面的SQL需要0.5秒

enter image description here

我做了另一个测试,163,840行非常快速地获得16.4个序列:

enter image description here

答案 1 :(得分:2)

(1)摆脱最内层的查询:

SELECT MIN(promo_id)
    FROM promotional
    GROUP BY mobile

(2)尝试使用amulti-table UPDATE。但由于两次引用同一个表,这可能会失败。

因此...

(3)使用临时表:

CREATE TEMPORARY TABLE t
        ( PRIMARY KEY(promo_id) )   -- To help with LEFT JOIN, below
    SELECT MIN(promo_id) AS promo_id
        FROM promotional
        GROUP BY mobile;
# do SELECT * FROM t; to see if it looks good
UPDATE promotional
    LEFT JOIN t USING(promo_id) 
    SET mobile = '', message_sent_status = 'BLANK'
    WHERE mobile != ''
      AND t.promo_id IS NULL;   -- replaces "NOT IN"

(4)考虑将mobile移到另一个表中,这样您就不必再这样做了。好像SELECT mobile, MIN(promo_id) FROM promotional GROUP BY mobile;会给你这样一张桌子。