MySQL - самый эффективный способ обрезки большого количества потерянных строк - PullRequest
0 голосов
/ 29 января 2019

Реорганизовав некоторый старый код, мы обнаружили, что объекты класса X создаются слишком часто, и ~ 80% из них остаются без ссылки.

У меня есть ~ 10 таблиц, которые ссылаются на строки втаблица класса X. Я легко могу определить количество осиротевших строк.Таблица содержит около 7 миллионов строк, и только около 1,5 миллионов представляют объекты, на которые есть законные ссылки.

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

Из-за моего ограниченного опыта администратора БД я знаю, как это сделать, - выбрать все допустимые идентификаторы объектов типа X, а затем сделать что-то вроде: DELETE FROM x WHERE id NOT IN (valid_references).Это примерно 10 триллионов сравнений, должен быть лучший способ.

1 Ответ

0 голосов
/ 30 января 2019

Размещаем это для любых будущих искателей.Проведя некоторые исследования, я обнаружил, что это идеальное решение, которое я мог бы составить.

Шаг 1: Создайте новую временную таблицу с точно такой же структурой, как та, которую мы пытаемся урезать по размеру,

Шаг 2: Определите таблицы / столбцы, которые ссылаются на рассматриваемый класс (X).

SELECT * 
FROM information_schema.COLUMNS 
WHERE table_schema = 'my_db_name' 
AND column_name LIKE '%reference_column%'

Шаг 3: Для каждой строки в этих таблицах / столбцах с ненулевой ссылкой,получить строку X, на которую они ссылаются, и скопировать ее в новую таблицу, если она еще не существует в новой таблице.Я делал эту таблицу за таблицей и использовал частичный подход по 1000 записей за раз, чтобы сэкономить системную память.Я написал эту логику на своем прикладном уровне, чтобы лучше ее контролировать.Я использовал INSERT IGNORE, чтобы избежать создания конфликтов первичных ключей, поскольку некоторые ссылки были на один и тот же X-объект.

Шаг 4. Удалите старую таблицу, переименуйте новую в то же имя, что и старая.

SET FOREIGN_KEY_CHECKS=0;
DROP TABLE old_table; 
RENAME TABLE new_table TO old_table;
SET FOREIGN_KEY_CHECKS=1;

Все говорят, что для запуска в моей среде, где таблица, требуется около часаУ X ~ 7 миллионов строк, и у меня есть ~ 10 других таблиц, ссылающихся на него.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...