2013-04-18 3 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 

Запрос для удаления дубликатов записей, которые друг от друга в ид = 50 с ид = 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

+0

Я обновляю ответ, просто проверяю, будет ли мой запрос работать вообще ... потому что когда там столбец внутри подзапроса и снаружи, Я не уверен :) – Justin

+0

Вот некоторые проблемы в вашем коде 'Вы не можете указать целевую таблицу 'f' для обновления в FROM clause' – Axeem

2

Я хотел бы попробовать это:

DELETE foo1 
FROM foo foo1 INNER JOIN foo foo2 
    ON foo1.link = foo2.link AND foo1.id>foo2.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

он также медленный. Как много времени взять его, чтобы завершить, если строки около 1,00,000. Любая идея ??? – Axeem

+0

Вы проверили ответ @fthiella. кажется, тесто. Попробуйте это –

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

+0

@ user2280065, с PHP это было бы не быстрее. Вы попробовали второе решение? – sectus

1

удалить из [таблица] где RowId не в (выберите мин (ROWID) из [таблицы] группы по [столбцов первичного ключа])

Это поможет в устранении duplicacy из таблицы на основе * ROWID'ы.

Смежные вопросы