2013-04-06 131 views
0

使用:MySQL的5.6在Windows,在my.ini的如何提高MySQL的DELETE查询性能

表默认的配置文件设置:datatbl1

row_id | emailaddr | valid 
-------------------------------- 
INT, PK | VARCHAR(255) | BIT 

两个EMAILADDR和ROW_ID每个都有一个指标定义的列。

表中有600,000行,目标是删除重复项。查询是:

delete dt2 from datatbl1 dt1 JOIN datatbl1 dt2 on (dt1.emailaddr = dt2.emailaddr) and (dt1.row_id < dt2.row_id); 

在我的系统,它需要大约15分钟才能完成此查询,我看mysqld进程在任务管理器,处理器使用的是整个时间的100%,但内存使用不穿过约140MB,即使安装了大约3GB的内存(RAM)和大量的可用内存。

问题:

  1. 我可以更改一些配置参数,以提高性能?
  2. 查询本身是否可以重写以提高性能?
  3. 用一两百万行来执行这个查询需要多长时间?

请记住,这个查询后需要被应用到其它表,即删除datatbl1比赛为匹配其他表(datatbl2,datatbl3,datatbl4等),它们具有相同的表结构的记录。

在我的客户端系统上,相同的查询需要2个小时。不同的是,他有一个正常的硬盘驱动器,而我有一个SSD。

该应用程序是一个带Delphi前端的客户端服务器应用程序,旨在供普通用户在Windows PC上使用,因此MySQL几乎总是在最终用户的Windows PC上运行。

在此先感谢。

编辑:根据要求 解释输出是:

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) 
+0

由于您没有使用'UNIQUE'关键字,这是一次性事件吗? – 2013-04-06 07:26:50

+0

你可以发布你的查询的'EXPLAIN'结果吗? – piotrekkr 2013-04-06 07:29:20

+0

@piotrekkr:发布解释结果。 – 2013-04-06 07:41:29

回答

1

也许这查询会更快:

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来查找并注意性能差异。

+0

它工作得很好。查询现在在4秒内完成并产生正确的结果。优秀! – 2013-04-06 13:00:49

+0

问题 - 删除row_id上的索引是否会产生负面影响?它已经是主要关键。 – 2013-04-06 13:01:50

+0

以类似的方式,并在相同的数据库中,是否有改进此查询的方法:“更新datatbl1 dt1连接datatbl2 dt2 (dt1.emailaddr = dt2.emailaddr)set valid = 0;” – 2013-04-06 13:24:31

0

您是否试图将row_idWHERE子句进行比较?

DELETE dt1 
FROM datatbl1 dt1 
INNER JOIN datatbl1 dt2 ON dt1.emailaddr = dt2.emailaddr 
WHERE dt1.row_id > dt2.row_id