Размер таблицы MySQL намного превышает размер данных в ней, что приводит к медленным запросам на сканирование индекса - PullRequest
1 голос
/ 10 апреля 2019

У меня есть таблица, которая вставляется и удаляется с высокой скоростью.Количество строк никогда не превышает нескольких сотен, и я не ожидаю, что оно будет больше нескольких мегабайт, но размер таблицы составляет 20 гигабайт и продолжает расти.Он использует MySQL 5.6.35, а движок - InnoDB.Я ожидаю, что вставленные строки будут вставлены в пространство, оставленное удаленными строками, но это не так.Он растет до этого уровня в течение недели, и в какой-то момент кажется, что запускается какой-то фоновый процесс, и он медленно уменьшается на несколько гигабайт.

Проблема, связанная с тем, что таблица настолько велика, что все запросы, сканирующие всю таблицу, например count(*), выполняются очень медленно.

Есть ли что-то, что я могу изменить, чтобы предотвратить такой рост стола?

Ответы [ 2 ]

0 голосов
/ 10 апреля 2019

InnoDB освобождает место при удалении, но не мгновенно. Он быстро помечает записи как удаленные, но пространство помечается свободным позже потоком очистки. Если вы продолжите быстро вставлять больше данных, вы, вероятно, заставляете InnoDB расширять табличное пространство, по крайней мере, часть времени, потому что вы пытаетесь повторно использовать пространство из удаленных строк до того, как они были очищены.

Например, читать:

Если вы вставляете и удаляете строки в маленьких пакетах с примерно одинаковой скоростью в таблице, поток очистки может начать отставать, и таблица может увеличиваться и увеличиваться из-за всех «мертвых» строк, делая все дисковое связано и очень медленно. В таком случае отрегулируйте новые операции над строками и выделите больше ресурсов для потока очистки, настроив системную переменную innodb_max_purge_lag. См. Раздел 14.14, «Параметры запуска InnoDB и системные переменные» для получения дополнительной информации.

Я никогда не сталкивался ни с одним сайтом, на котором установлен innodb_max_purge_lag, потому что это означает, что их продолжительная запись в базу данных иногда может быть замедлена. Обычно они этого не хотят.

Вместо этого я установил innodb_purge_threads=4 вместо значения по умолчанию 1. Это помогает очистке быстро действовать при запуске.

Очистка еще больше откладывается, если ваше приложение поддерживает открытые транзакции, которым необходимо хранить эти удаленные строки, чтобы удовлетворить их представление REPEATABLE-READ базы данных. Не имеет значения, насколько быстро выполняется очистка или сколько потоков необходимо выполнить, если очистка предотвращена требованиями моментальных снимков открытых транзакций.

Вы должны оперативно совершать транзакции и не оставлять их открытыми в течение неопределенного периода времени. Или измените уровень изоляции транзакции на READ-COMMITTED, чтобы вашим транзакциям не требовалась база данных для сохранения старых версий записей.

0 голосов
/ 10 апреля 2019

Попробуйте OPTIMIZE TABLE для этой таблицы.

OPTIMIZE TABLE реорганизует физическое хранилище табличных данных и связанные данные индекса, чтобы уменьшить объем памяти и улучшить ввод-вывод эффективность при доступе к таблице. Точные изменения, внесенные в каждый Таблица зависит от механизма хранения, используемого этой таблицей.

https://dev.mysql.com/doc/refman/5.6/en/optimize-table.html

...