下面的MySQL命令在现代PC上运行超过4秒,其中没有其他任何东西运行,即使多次运行:
DELETE FROM table1
WHERE column1 LIKE 'pattern1%' AND
column2 IN (SELECT column3 FROM table2 WHERE column4 = 'pattern2')
table1包含约。 1100记录,其中95%匹配column1 / pattern1%。
table2包含约。其中5000个接近零,匹配column4 / pattern2。
主机:MySQL v5.7,Ubuntu 16 64位,快速SSD,InnoDB池内存为1 GB
可以用更简单或更快的方式完成吗?感谢。
查询计划:
+----+--------------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+--------------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | DELETE | table1 | NULL | ALL | NULL | NULL | NULL | NULL | 1179 | 100.00 | Using where |
| 2 | DEPENDENT SUBQUERY | table2 | NULL | ALL | NULL | NULL | NULL | NULL | 4601 | 1.00 | Using where |
+----+--------------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+
答案 0 :(得分:1)
这取决于表的大小和索引配置。
例如,如果table2不是太大,由column4正确索引,并且subselect的结果也不大,你可以颠倒条件的顺序,以便首先执行column2条件,如果它没有' t匹配,它不会打扰执行可能较慢的column1之类的查询。
DELETE FROM table1
WHERE column2 IN (SELECT column3 FROM table2 WHERE column4 = 'pattern2') AND
column1 LIKE 'pattern1%'
答案 1 :(得分:1)
从EXPLAIN
查询中可以看出,您的表没有正确设置索引。索引用于快速查找具有特定列值的行。
从索引的性能角度来看,最重要的用途之一是找到行匹配一个WHERE
子句快速。如果没有索引,MySQL 必须从第一行开始,然后通过整个表读取以查找相关行。表越大,成本越高。如果表中有相关列的索引,MySQL可以快速确定要在数据文件中间寻找的位置,而无需查看所有数据。这比按顺序读取每一行要快得多。
答案 2 :(得分:0)
您需要添加索引以加快查询速度。至少应该在column 4
table 2
上有一个索引。您可能希望在(column 4, column3)
上创建组合索引。
由于您指出table 1
中约95%的所有行都与column 1
匹配,因此添加column 1
的索引毫无意义。如果column 2
的匹配数相对较少,则可以为该列添加索引。
答案 3 :(得分:0)
我终于通过向table2 / column3添加索引来解决它。感谢大家的帮助。