如何提高MySQL删除查询性能
在Windows上使用:MySQL 5.6,在my.ini中使用默认配置文件设置 表:datatbl1如何提高MySQL删除查询性能,mysql,performance,Mysql,Performance,在Windows上使用:MySQL 5.6,在my.ini中使用默认配置文件设置 表:datatbl1 row_id | emailaddr | valid -------------------------------- INT, PK | VARCHAR(255) | BIT emailaddr和row_id列都定义了索引 表中有600000行,目标是删除重复项。查询是: delete dt2 from datatbl1 dt1 JOIN datatbl1 dt2 on (
row_id | emailaddr | valid
--------------------------------
INT, PK | VARCHAR(255) | BIT
emailaddr和row_id列都定义了索引
表中有600000行,目标是删除重复项。查询是:
delete dt2 from datatbl1 dt1 JOIN datatbl1 dt2 on (dt1.emailaddr = dt2.emailaddr) and (dt1.row_id < dt2.row_id);
delete dt2 from datatbl1 dt1 JOIN datatbl1 dt2 on(dt1.emailaddr=dt2.emailaddr)和(dt1.row\u id
在我的系统上,完成这个查询大约需要15分钟,我在任务管理器中观察mysqld进程,处理器使用率始终为100%,但内存使用率从未超过大约140MB,即使安装了大约3GB的内存(RAM)和大量可用内存
问题:
mysql> explain delete dt2 from datatbl1 dt1 JOIN datatbl1 dt2 on (dt1.emailaddr
= dt2.emailaddr) and (dt1.row_id < dt2.row_id);
+----+-------------+-------+-------+------------------------------+-------------
+---------+--------------------------+------+-------------+
| id | select_type | table | type | possible_keys | key
| key_len | ref | rows | Extra |
+----+-------------+-------+-------+------------------------------+-------------
+---------+--------------------------+------+-------------+
| 1 | SIMPLE | dt1 | index | PRIMARY,ixemailaddr,ixrow_id | ixemailaddr
| 257 | NULL | 1 | Using index |
| 1 | SIMPLE | dt2 | ref | PRIMARY,ixemailaddr,ixrow_id | ixemailaddr
| 257 | emailmgrdb.dt1.emailaddr | 1 | Using where |
+----+-------------+-------+-------+------------------------------+-------------
+---------+--------------------------+------+-------------+
2 rows in set (0.01 sec)
mysql>解释从datatbl1 dt1删除dt2在(dt1.emailaddr)上加入datatbl1 dt2
=dt2.emailaddr)和(dt1.row_id
也许这个查询会更快:
DELETE dt1.*
FROM datatbl1 dt1
JOIN (SELECT emailaddr, MIN(row_id) minrow
FROM datatbl1
GROUP BY emailaddr) dt2
USING (emailaddr)
WHERE dt1.row_id > dt2.minrow
原始查询中的中间表的大小是O(n^2)(因为它将每一行与它后面的所有重复项连接起来),但这个中间表的大小是O(n)(因为它只将每组重复项的第一行与它后面的重复项连接起来)
这取决于查找行或执行所有删除时的慢度。您可以通过执行SELECT而不是DELETE并注意性能差异来发现这一点。您是否尝试将
行id
比较移动到WHERE
子句
DELETE dt1
FROM datatbl1 dt1
INNER JOIN datatbl1 dt2 ON dt1.emailaddr = dt2.emailaddr
WHERE dt1.row_id > dt2.row_id
这是因为你没有使用
UNIQUE
关键字而导致的一次性事件吗?你能发布一个EXPLAIN
查询结果吗?@piotrekkr:EXPLAIN result posted.@SteveF-问题是你将来是否要使用UNIQUE
来避免这个问题,因此只需要这样做一次?@SteveF-IMHO我认为你应该这样做重新设计数据库,使其使用3NFIt非常有效。查询现在在4秒内完成,并生成正确的结果。杰出!问题-删除行_id上的索引会对差异产生负面影响吗?它已经是一个主键。类似地,在同一个数据库中,是否有改进此查询的方法:“更新datatbl1 dt1加入datatbl2 dt2 on(dt1.emailaddr=dt2.emailaddr)设置valid=0;”主键会自动索引,因此不需要为其设置单独的索引。我认为,只要两个表在emailaddr上都有索引,更新查询就应该可以正常工作。