2010-05-21 33 views
1

刪除數據我在做這樣:最快從MySQL

delete from calibration_2009 where rowid in 
(SELECT rowid FROM `qcvalues`.`batchinfo_2009` where reporttime like "%2010%"); 

我需要有250K左右的行刪除。

爲什麼需要這麼長時間?有沒有更快的方法來做到這一點?

+0

'reporttime'是一個字符串,而不是日期時間? – 2010-05-21 18:01:11

+0

糾正它是一個字符串,不幸的是 – 2010-05-21 18:01:51

回答

1
DELETE c 
FROM `qcvalues`.`batchinfo_2009` b 
JOIN calibration_2009 c 
ON  c.rowid = b.rowid 
WHERE b.reporttime LIKE '%2010%'; 

你應該有一個索引calibration_2009 (rowid)爲此工作得很快。

無論如何,我認爲這是一個PRIMARY KEY,但你最好檢查一下。

+0

這會刪除batchinfo或校準嗎? – 2010-05-21 18:12:06

+0

@evert:當然是來自校準。如果你想從兩個表中刪除,使用'DELETE b,c FROM ...' – Quassnoi 2010-05-21 18:16:51

+0

沒有。 rowid不是它的主鍵 – 2010-05-21 18:47:17

1

如果reporttime是DATETIME,使用:

DELETE FROM calibration_2009 
WHERE rowid IN (SELECT rowid 
        FROM `qcvalues`.`batchinfo_2009` 
        WHERE reporttime BETWEEN STR_TO_DATE('2010-01-01', '%Y-%m-%d') 
             AND STR_TO_DATE('2010-12-31', '%Y-%m-%d')) 
0

不知道這是否是有效的客棧MySQL,但你試過

delete from calibration_2009 a inner join qcvalues.batchinfo_2009 b on a.rowid = b.rowid where reporttime like '%2010%'

另外,如果年份部分是在一個固定的位置在reporttime內嘗試使用子字符串和等號而不是使用LIKE語句

1

取決於有多少行內部選擇返回,你必須在calibration_2009中每行進行多次比較,看它是否必須被刪除。

如果inner select返回250k行,那麼您在calibration_2009中每行最多進行250k比較,以查看是否應該刪除該行。

我想說一個更快的方法是將一列添加到calibration_2009,如果可能的話,稱爲to_be_deleted。然後更新該表

UPDATE calibration_2009 SET to_be_deleted = EXISTS (
    SELECT 1 FROM `qcvalues`.`batchinfo_2009` 
    WHERE `batchinfo_2009.rowid = calibration_2009.rowid AND batchinfo_2009.reporttime like "%2010%" 
); 

如果兩個表是通過在batchinfo_2009 ROWID和reporttime收錄這應該是相當快的。

然後,只需

DELETE FROM calibration_2009 WHERE to_be_deleted = 1; 

然後你就可以刪除新的領域,或者留爲未來的更新。

+0

這需要很長的時間 – 2010-05-21 18:39:40

+0

無論如何,不​​要指望大量的數據在快照中被處理......每個表中有多少行?如果你有幾百萬,那麼...坐下來等待:) – Seb 2010-05-21 19:16:06