Если требуется удалить большие объёмы данных из таблиц 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 ;
Комментариев нет:
Отправить комментарий