我想更改 table_one 中此列的值,其中此 = 1且 id 值为该行存在于 table_two 的列 other_id
中的任何位置所以我正在使用此查询:
UPDATE table_one SET this='0' WHERE this='1' AND table_one.id IN (SELECT other_id FROM table_two);
查询花了几个小时没有完成,所以我想知道是否有办法更快地完成它。
如果重要的话, table_one.id 和 table_two.other_id 都有唯一值。
table_one 有550k行
table_two 有30k行
MySQL 5.0.22
答案 0 :(得分:1)
尝试使用EXISTS代替IN
答案 1 :(得分:1)
UPDATE...JOIN
是 tuffkid 和 Brian Hooper 提供的EXISTS
答案的替代方案。我已经测试了两者,他们都花了相同的时间(我的电脑上2.52秒):
UPDATE table_one
JOIN table_two
ON table_one.id = table_two.other_id
SET this=0
WHERE table_one.this=1;
应该对已加入的列编制索引,如果table_two.other_id
具有UNIQUE
索引,则查询应该运行得非常快。
示例强>
创建表格:
CREATE TABLE `table_one` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`this` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `this` (`this`)
);
CREATE TABLE `table_two` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`other_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `other_id` (`other_id`)
);
插入一些测试数据:
DELIMITER //
DROP PROCEDURE IF EXISTS populate//
CREATE PROCEDURE populate()
BEGIN
DECLARE i INT DEFAULT 0;
WHILE i < 550000 DO
INSERT INTO table_one (this) VALUES ((i MOD 18)+1);
IF i MOD 18 = 0 THEN
INSERT INTO table_two (other_id) VALUES (i+1);
END IF;
SET i = i + 1;
END WHILE;
END;
//
DELIMITER ;
CALL populate();
运行更新:
UPDATE table_one
JOIN table_two
ON table_one.id = table_two.other_id
SET this=0
WHERE table_one.this=1;
Query OK, 30556 rows affected (2.52 sec)
Rows matched: 30556 Changed: 30556 Warnings: 0
UPDATE table_one
SET this=0
WHERE this=1 AND
EXISTS (SELECT other_id
FROM table_two
WHERE other_id = table_one.id);
Query OK, 30556 rows affected (2.52 sec)
Rows matched: 30556 Changed: 30556 Warnings: 0
答案 2 :(得分:0)
扩展tuffkid的答案......
UPDATE table_one
SET this='0'
WHERE this='1' AND
EXISTS (SELECT other_id
FROM table_two
WHERE other_id = table_one.id);
答案 3 :(得分:-1)
实际上解决方案是为table_one.id和table_two.other_id添加索引。 我提到它们是独一无二的,但我并不是说它们有索引,所以我不好澄清它。
添加索引后,查询花了不到一分钟。
同样用EXISTS替换IN会给我一个语法错误,所以我坚持使用IN。