Как оптимизировать таблицы InnoDB в MySQL

8

Я изучал, как оптимизировать только фрагментированные таблицы в MySQL, и рассмотрел этот пост по оптимизации таблиц . Он в основном выполняет запрос к базе данных information_schema для любой таблицы data_free > 0и создает инструкцию SQL OPTIMIZEтолько для этих таблиц. Я выполнил этот запрос, и он определил 148 таблиц для оптимизации. Все указанные таблицы являются таблицами InnoDB. После выполнения результирующего сценария SQL оптимизации я повторно запустил исходный сценарий, чтобы определить фрагментированные таблицы, и он возвратил точно такие же таблицы во время первого прохода.

Я видел противоречивые сообщения, касающиеся таблиц InnoDB и OPTIMIZEкоманды. Некоторые говорят, что OPTIMIZEне будет работать с таблицами InnoDB и что вам нужно работать ALTER TABLE table_name ENGINE=INNODB. Другие говорят, что OPTIMIZEфактически вызывает ALTER TABLEкоманду при выполнении с таблицами InnoDB. Имея это в виду, я запустил ALTER TABLEкоманду для одной из таблиц InnoDB, идентифицированных как фрагментированные ( data_free > 0), и обнаружил, что data_freeвпоследствии она не изменилась. Это все еще больше чем 0. Я также перезапустил MySQL и проверил это только, чтобы найти те же самые результаты.

Теперь у нас есть несколько серверов с MySQL 5.5.29 в нашей организации, и я выполнил запрос ко всем из них, чтобы идентифицировать любые таблицы InnoDB, DATA_FREE=0 or NULLи ни один из них не был возвращен. Все они больше нуля.

Я также запустил OPTIMIZEкоманду для нескольких MyISAMтаблиц, значение которых DATA_FREEбыло больше нуля, и впоследствии проверил, что оно было равно нулю.

Кто-нибудь может пролить свет на это для меня? Как правильно удалить фрагменты из таблиц InnoDB? Как правильно определить фрагментированные таблицы InnoDB?

Спасибо

user3151788
источник

Ответы:

9

Я предполагаю, что вы используете innodb_file_per_tableдля этого ответа.

Существует несколько значений «фрагментации InnoDB»:

  1. .ibd файл фрагментирован и очень большой, тогда как набор данных мал
  2. Индексные страницы фрагментированы в связи с тем, что слишком много страниц содержат мало данных, и в этом случае их можно объединить.

Пожалуйста, обратите внимание на этот пост, который я написал некоторое время назад: он показывает, как после очистки большого количества строк из большой таблицы файл данных фрагментируется (т.е. он очень большой в файловой системе - это известная проблема, которую эти файлы никогда не уменьшают в размере). И все же индексы не были фрагментированы к концу удаления: это потому, что InnoDB правильно объединяет страницы, когда они становятся пустыми (er).

Команда OPTIMIZEдействительно не относится к InnoDB. Что он делает, это восстановить таблицу (точно так же, как ALTER). Посмотри это:

mysql [localhost] {msandbox} (test) > create table t(id int) engine=innodb;

mysql [localhost] {msandbox} (test) > optimize table t;
+--------+----------+----------+-------------------------------------------------------------------+
| Table  | Op       | Msg_type | Msg_text                                                          |
+--------+----------+----------+-------------------------------------------------------------------+
| test.t | optimize | note     | Table does not support optimize, doing recreate + analyze instead |
| test.t | optimize | status   | OK                                                                |
+--------+----------+----------+-------------------------------------------------------------------+

Что касается DATA_FREE: я предлагаю вам просто игнорировать эту переменную. Честно говоря, я годами работал с таблицами InnoDB 10и никогда не находил, чтобы это значение было чем-то очень совместимым.

А теперь пришло время для реальной дискуссии: чего именно вы пытаетесь достичь? Если ваша база данных полностью не устарела, всегда будет некоторая фрагментация. Это естественно для процесса добавления, удаления и обновления строк в вашей таблице.

Фрагментация - не то зло: свободное место может быть восстановлено новыми данными. Если ваши столы не очень большие, то просто забудьте обо всем. Для очень больших таблиц вы можете получить немного дискового пространства за счет оптимизации таблицы. Но спросите себя: как скоро стол достигнет такой же фрагментации? Час? День? Неделя? ИМХО во всех этих случаях бессмысленно оптимизировать таблицу.

Тем не менее, если большая таблица очищена от данных, которые не должны возвращаться, я полностью за ее оптимизацию. Скажем, вы понимаете, что у вас есть избыточные данные, которые составляют около 30% размера вашей таблицы. Конечно, было бы здорово вернуть это дисковое пространство.

Итог: рассмотрите эти проблемы только с очень большими таблицами; только если у вас есть проблемы с дисковым пространством.

Шломи Ноах
источник
Я согласен, что data_free не является полезным. Он только считает пространство в «свободных экстентах» для табличного пространства, что является ужасным показателем для расчета фрагментации. Я думаю, что если вы не используете innodb_file_per_tableего, он также покажет одно и то же значение для каждой таблицы в общем табличном пространстве.
Джеремиколе