2013-04-06 15 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