簡體   English   中英

如何提高MySQL DELETE查詢性能

[英]How to improve MySQL DELETE query performance

使用:Windows上的MySQL 5.6,在my.ini中具有默認配置文件設置

表: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%,但是即使大約有3GB內存,內存使用也從未超過140MB(內存)和足夠的可用內存。

問題:

  1. 我可以更改一些配置參數以提高性能嗎?
  2. 查詢本身可以重寫以提高性能嗎?
  3. 用1-200萬行執行此查詢的合理時間是多少?

請記住,此查詢以后需要應用於其他表,即刪除與具有相同表結構的其他表(datatbl2,datatbl3,datatbl4等)匹配的記錄的datatbl1中的匹配項。

在我的客戶的系統上,相同的查詢需要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)

也許此查詢會更快:

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並注意性能差異來找出答案。

您是否嘗試過將row_id比較移至WHERE子句?

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM