MySQL - 更新 - 更快的解决方案?

时间:2015-08-12 10:06:13

标签: mysql sql mariadb

我想加快一些脚本,所以我的问题是:有更快的解决方案吗?

uid只是添加到临时表中的ID 之后,它使用给定的uid更新原始表。

引擎是InnoDB,MariaDB 10.0.19。

约400个条目需要大约20秒。

CREATE TEMPORARY TABLE cleanup_users AS (
    SELECT uid FROM users
    WHERE FROM_UNIXTIME(last_connect) <= DATE_SUB(NOW(), INTERVAL 2 MONTH)
    AND activity <= 20 AND hide != 1
);
UPDATE users SET hide = 1 WHERE uid IN (
    SELECT * FROM cleanup_users
);
DROP TABLE IF EXISTS cleanup_users;

3 个答案:

答案 0 :(得分:3)

UPDATE users SET hide = 1 WHERE last_connect <= UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 2 MONTH)) AND activity <= 20 AND hide != 1

不要在where子句中的列上使用函数,并添加覆盖索引以加速处理。

ALTER TABLE users ADD INDEX(last_connect,activity,hide);

答案 1 :(得分:0)

首先,您不需要创建新表

UPDATE users SET hide = 1 WHERE uid IN (
    SELECT uid FROM users
    WHERE FROM_UNIXTIME(last_connect) <= DATE_SUB(NOW(), INTERVAL 2 MONTH)
    AND activity <= 20 AND hide != 1
);

而且,我认为你可以做到这一点。

UPDATE users SET hide = 1 WHERE
      FROM_UNIXTIME(last_connect) <= DATE_SUB(NOW(), INTERVAL 2 MONTH) AND activity <= 20 AND hide != 1

答案 2 :(得分:0)

即使您需要更新来自不同表的数据匹配,也不需要临时表,在当前情况下,可以使用一个查询来完成

update users 
set hide = 1 
where
last_connect <= unix_timestamp(DATE_SUB(NOW(), INTERVAL 2 MONTH))
activity <= 20 AND hide != 1

现在假设表中涉及大量数据,您需要一些索引,并且您可以使用以下覆盖索引

alter table users add index date_act_hide_idx(last_connect,activity,hide);

确保在应用索引之前备份表。

现在请注意,删除FROM_UNIXTIME的where子句发生了更改,并且在比较的右侧使用了unix_timestamp,迫使它使用列{{1}上的索引}