2013-04-18 112 views
0

從大表(500000+行)中刪除破壞行的最佳方式是什麼?
我有一個代碼,它運作良好,但它不夠快。
這是一個代碼。以更快的方式從表格中刪除破壞行

DELETE foo 
FROM foo 
    INNER JOIN (SELECT 
     link, 
     MIN(id) AS MinId 
      FROM foo 
      GROUP BY link) b 
    ON foo.link = b.link 
     AND foo.id != b.MinId 

請告訴我其他任何比這段代碼更快的方法。
謝謝.......

回答

0

查詢:

DELETE f 
FROM foo f 
WHERE (SELECT MIN(f1.id) 
     FROM (SELECT * FROM foo) f1 
     WHERE f1.link = f.link) != f.id 

查詢,以去除之間的ID = 50至ID = 100重複記錄:

DELETE f 
FROM foo f 
WHERE (SELECT MIN(f1.id) 
     FROM (SELECT * FROM foo) f1 
     WHERE f1.link = f.link) != f.id 
AND f.id >= 50 
AND f.id <= 100 
+0

我如何使用這段代碼來刪除ID = 50到ID = 100之間的破壞行 – Axeem 2013-04-19 07:17:11

+0

我更新了答案,只是testit如果我的查詢可以工作......因爲當子列表裏面有列和外面的時候,我不確定:) – Justin 2013-04-19 07:54:15

+0

你的代碼中存在一些問題'你無法在FROM子句中指定更新目標表'f' – Axeem 2013-04-19 16:38:48

2

我想試試這個:

DELETE foo1 
FROM foo foo1 INNER JOIN foo foo2 
    ON foo1.link = foo2.link AND foo1.id>foo2.id 

這將只保留具有最小ID的鏈接。

0

試試這個

DELETE foo 
FROM foo 
    INNER JOIN (SELECT 
       link, 
       MIN(id) AS MinId 
      FROM foo 
      GROUP BY link) b 
    ON foo.link = b.link 
WHERE foo.id <> b.MinId 
+0

它也很慢。如果行數大約是100,000,那麼多少時間才能完成。任何想法? – Axeem 2013-04-18 07:52:14

+0

你檢查了@fthiella的答案嗎?看起來連擊。試試那一個 – 2013-04-18 07:55:26

0

短道:添加約束

ALTER IGNORE TABLE `foo` ADD UNIQUE `link` (`link`); 
DROP INDEX `link` ON `foo`; -- to restore table state 

但我認爲最好創建新表與約束

CREATE TABLE `temp` LIKE `foo`; 
ALTER IGNORE TABLE `temp` ADD UNIQUE `link` (`link`); 
INSERT IGNORE INTO `temp` SELECT * FROM `foo`; 
RENAME TABLE `foo` TO `old_foo`, `temp` TO `foo`; 
DROP TABLE `old_foo`; 
DROP INDEX `link` ON `foo`; -- to restore table state 

沒有測試。

P.S.不要忘記鎖表

P.P.S.表格不能鎖定。無論如何,您必須在操作前停止寫入該表格。

+0

所有的問題都很好。謝謝你的幫助。我意識到我的電腦太慢了,無法執行這個任務。現在我打算爲此做一個php代碼。總之感謝所有人。 – Axeem 2013-04-18 14:33:17

+0

@ user2280065,用PHP它不會更快。你嘗試第二種解決方案嗎? – sectus 2013-04-19 00:53:20

1

刪除 [表] 其中ROWID未在(SELECT MIN(從[表] 組由[主鍵列] ROWID) )

它將在去除從表中duplicacy幫助基於的rowid。