Если требуется удалить большие объёмы данных из таблиц MySQL, это занимает слишком много времени.
Ускорить процесс может такая процедура.
# Пример использования процедуры: # CALL cut_table('my_cool_table'); DROP PROCEDURE IF EXISTS cut_table; DELIMITER // CREATE PROCEDURE cut_table(IN tableName CHAR(255)) BEGIN SET @tableName = tableName; SET @tableNameOld = CONCAT(@tableName, '_old'); SET @tableNameCopy = CONCAT(@tableName, '_copy'); # Количество строк, которые мы оставляем в начале и конце таблицы. SET @skipCount = 10000; # Считаем общее количество строк в таблице. SET @sql_text = CONCAT('SELECT count(*) INTO @totalRows FROM ', @tableName); PREPARE stmt FROM @sql_text; EXECUTE stmt; DEALLOCATE PREPARE stmt; SELECT @totalRows; SET @minRows = @skipCount*2; # Если строк мало, то не обрезаем таблицу. # Эта проверка спасает нас, если мы вызовем скрипт дважды для одной таблицы. IF (@totalRows <= @minRows) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Table has too few rows. No need to suck it.'; END IF; # Создаём структурную копию таблицы. # Внешние ключи не копируются, их требуется задать отдельно. SET @sql_text = CONCAT('CREATE TABLE ', @tableNameCopy, ' LIKE ', @tableName); PREPARE stmt FROM @sql_text; EXECUTE stmt; DEALLOCATE PREPARE stmt; # Копируем те данные, которые нам нужны. SET @sql_text = CONCAT('INSERT INTO ', @tableNameCopy, ' SELECT * FROM ', @tableName, ' ORDER BY id ASC LIMIT ?'); PREPARE stmt FROM @sql_text; EXECUTE stmt USING @skipCount; DEALLOCATE PREPARE stmt; SET @sql_text = CONCAT('INSERT INTO ', @tableNameCopy, ' SELECT * FROM ', @tableName, ' ORDER BY id DESC LIMIT ?'); PREPARE stmt FROM @sql_text; EXECUTE stmt USING @skipCount; DEALLOCATE PREPARE stmt; # Переименовываем таблицы, замещая старую таблицу новой. SET @sql_text = CONCAT('RENAME TABLE ', @tableName, ' TO ', @tableNameOld, ', ', @tableNameCopy, ' TO ', @tableName); PREPARE stmt FROM @sql_text; EXECUTE stmt; DEALLOCATE PREPARE stmt; # Удаляем старую таблицу. SET @sql_text = CONCAT('DROP TABLE ', @tableNameOld); PREPARE stmt FROM @sql_text; EXECUTE stmt; DEALLOCATE PREPARE stmt; END // DELIMITER ;