Как быстро обрезать большие столы? - PullRequest
5 голосов
/ 11 июля 2010

У меня в настоящее время MySQL таблица около 20 миллионов строк, и мне нужно ее сократить.Я хотел бы удалить каждую строку, чья updateTime (отметка времени вставки) была более месяца назад.Я лично не вносил никаких изменений в порядок таблицы, поэтому данные должны быть в том порядке, в котором они были вставлены, а на двух полях есть клавиша UNIQUE, id и updateTime.Как мне поступить так за короткий промежуток времени?

Ответы [ 4 ]

13 голосов
/ 11 июля 2010

Сколько времени простоя вы можете понести? Насколько большие строки? Сколько вы удаляете?

Проще говоря, удаление строк является одной из самых дорогих вещей, которые вы можете сделать с таблицей. Это просто ужасная вещь.

Если вам не нужно это делать, и у вас есть для этого место на диске, и на размер ваших запросов не влияет размер таблицы (хорошо проиндексированные запросы обычно игнорируют размер таблицы), то вы можете просто оставить достаточно хорошо один.

Если у вас есть возможность и вы можете перевести таблицу в автономный режим (и вы удаляете хороший процент от таблицы), то лучшим вариантом будет скопировать строки, которые вы хотите сохранить, в новую таблицу, отбросив старую. один, переименуйте новый в старое имя, а затем воссоздайте свои индексы.

В противном случае вы в значительной степени застряли с хорошим удалением.

13 голосов
/ 11 июля 2010

Есть два способа удалить большое количество строк.Во-первых, есть очевидный способ:

DELETE FROM table1 WHERE updateTime < NOW() - interval 1 month;

Второй (немного более сложный) способ - создать новую таблицу и скопировать данные, которые вы хотите сохранить, обрезать старую таблицу, а затем скопировать строки обратно..

CREATE TABLE table2 AS
SELECT * FROM table1 WHERE updateTime >= NOW() - interval 1 month;

TRUNCATE table1;

INSERT INTO table1
SELECT * FROM table2;

Использование TRUNCATE намного быстрее, чем DELETE с предложением WHERE, когда у вас есть большое количество строк для удаления и относительно небольшое количество, которое вы хотите сохранить.

0 голосов
/ 10 августа 2013

На самом деле, даже если вы не можете перевести таблицу в автономный режим надолго, вы все равно можете использовать технику «переименования таблицы», чтобы избавиться от старых данных.

Остановить процессы записи в таблицу.

rename table tableName to tmpTableName;
create table tableName like tmpTableName;
set @currentId=(select max(id) from tmpTableName);
set @currentId=@currentId+1;
set @indexQuery = CONCAT("alter table test auto_increment = ", @currentId);
prepare stmt from @indexQuery;
execute stmt;
deallocate prepare stmt;

Запустить процессы записи в таблицу.

insert into tableName
select * from tmpTableName;
drop table;

Новые вставки в tableName начнутся с правильного индекса;Старые данные будут вставлены в правильные индексы.

0 голосов
/ 23 марта 2013

Разделение удалений с лимитом может ускорить процесс;

Мне пришлось удалить 10M строк, и я дал команду. Он никогда не отвечал часами.

Я убил запрос (который занял пару часов)

затем разделить удаляет.

DELETE from table where id > XXXX limit 10000;
DELETE from table where id > XXXX limit 10000;
DELETE from table where id > XXXX limit 10000;
DELETE from table where id > XXXX limit 10000;

Затем я продублировал это утверждение в файле и использовал команду.

mysql> source /tmp/delete.sql 

Это было намного быстрее.

Вы также можете попробовать использовать такие инструменты, как pt-tools. и pt-архиватор.

...