|
|
|
Вопросы после переноса таблицы с MyISAM на InnoDB
|
|||
|---|---|---|---|
|
#18+
На MySQL 5.7.24 живет табличка на движке MyISAM. Табличка поделена на 12 партиций - по числу месяцев. Работает давно и вопросов не вызывает. Запись в таблицу сравнительно редкая, преимущественно чтение используется. Количество записей нынче порядка 16 миллионов и растет. В таблице 8 полей: два поля INT, три TINYINT, одно MEDIUMINT, одно DATE и одно VARCHAR(255). Все поля NOT NULL. Однако, при обновлении версии сервера давно уже стало появляться предупреждение "The partition engine, ...., is deprecated and will be removed in a future release.". Документация говорит следующее: https://dev.mysql.com/doc/refman/8.0/en/partitioning.html In MySQL 8.0, partitioning support is provided by the InnoDB and NDB storage engines. MySQL 8.0 does not currently support partitioning of tables using any storage engine other than InnoDB or NDB, such as MyISAM. Ясно-понятно, есть смысл протестировать переезд заблаговременно. На тестовой базе делаю резервную копию таблицы, а затем для рабочей делаю ALTER TABLE ... ENGINE=InnoDB;, как сказано в мануале по переезду . Вместо предполагаемых ориентировочно 30...40 минут (так то заливка дампа в 15 минут легко укладывается) запрос работал часа полтора. Ну это ладно, я же не знаю, как работает внутренняя кухня. Тем не менее, вопрос первый : чего он так долго ковырялся, это так и должно быть? Конвертация завершилась. Смотрю статистику таблицы. На MyISAM исходная таблица (как и бэкап её) весит 1,9 гига , из них треть примерно данные, остальное - индексы (индексов там много, да). Цифра привычная и ожидаемая. На InnoDB после ALTER TABLE таблица весит уже 5,7 гиг , соотношение данные/индекс (смотрел в phpmyadmin) похожее. Посмотрел размеры (опция innodb_file_per_table включена) файлов в датадир - ну да, сопоставимо, каждый файл *.ibd для этой таблицы порядка 500 мегабайт, ну плюс-минус, конечно. Вопрос второй : с чего так распухли файлы? В мануале по переезду на InnoDB сказано: https://dev.mysql.com/doc/refman/8.0/en/converting-tables-to-innodb.html InnoDB tables require more disk space than MyISAM tables.Но не нашел, насколько больше. Втрое больше - ад какой-то. Хорошо, есть же ещё способ. Делаю дамп таблицы. Делаю новую пустую таблицу InnoDB с копией структуры. Заливаю дамп в пустую таблицу. Время заливки ожидаемо, но размер получился уже 3,1 гига при том же соотношении данные/индекс. Ага, больше чем в MyISAM, но уже не втрое, а лишь в полтора раза. Смотрю в датадир файлы этой таблицы - в среднем порядка 300 мегабайт на файл. Вот тут уже не понимаю. Данные те же, а размеры файлов сильно разные. Опять же вопрос третий : оно получилось где-то посередине, но почему? Ну так то, конечно, способ получения файлов таблицы разный, хотя, данные идентичны и в количестве и в типе полей, да и в значениях, надеюсь... Или есть различия? Для начала просто проверяю количество строк запросом SELECT COUNT(1) FROM .... И опять же, пляска. На MyISAM: Код: plaintext 1. 2. 3. 4. 5. Код: plaintext 1. 2. 3. 4. 5. 6. Для чистоты эксперимента тот же запрос к таблице, куда заливал дамп. Количество строк ожидаемо то же самое, время выполнения не ноль, конечно, но от 4 до 15 секунд колеблется. Ладно, сойдет. Но многократная разница времени выполнения по сравнению с предыдущим намекает на какие-то проблемы. В общем, по итогу тестирования закралось сомнение в правильности работы ALTER TABLE. Выходит, этот запрос выдал в результате не только не в меру пухлую по размерам файлов таблицу, но и какую-то тормозную, чтоли... Вопрос : есть какие-то противопоказания применения ALTER TABLE или чего я не учел ещё? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2018, 22:57 |
|
||
|
Вопросы после переноса таблицы с MyISAM на InnoDB
|
|||
|---|---|---|---|
|
#18+
vkleVARCHAR(255)А что с кодировкой этого поля до и после? В целом, единственное, что приходит в голову - при разных способах заливки данных разный порядок записей приведет к разному их раскладыванию на диске. Но оценить численно не берусь. Я бы предложил выгрузить дамп (или TSV) в порядке первичного ключа (а он, кстати, есть?) и загрузить его в свежесозданную таблицу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2018, 03:04 |
|
||
|
Вопросы после переноса таблицы с MyISAM на InnoDB
|
|||
|---|---|---|---|
|
#18+
miksoftvkleVARCHAR(255)А что с кодировкой этого поля до и после?Без изменений, utf8_general_ci. Да и там только латиница ЕМНИП. miksoftЯ бы предложил выгрузить дамп (или TSV) в порядке первичного ключа (а он, кстати, есть?) и загрузить его в свежесозданную таблицу.Специального первичного ключа, основанного на каком-то одном поле в таблице нет. Однако, для нужд приложения имеется составной уникальный индекс по нескольким полям. В принципе, можно в любом порядке скопировать данные в пустую таблицу при помощи INSERT...SELECT, например. Но что это даст или что следует ожидать от такого теста? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2018, 03:24 |
|
||
|
Вопросы после переноса таблицы с MyISAM на InnoDB
|
|||
|---|---|---|---|
|
#18+
vkleСпециального первичного ключа, основанного на каком-то одном поле в таблице нет.А вот с этого места поподробнее. Желательно с полным DDL. У InnoDB есть фича - если нет явно назначенного первичного ключа или подходящего уникального, то он создает для этого техническое невидимое поле размером 6 байт, которое будет храниться и в таблице, и в каждом индексе. https://dev.mysql.com/doc/refman/8.0/en/innodb-index-types.html If the table has no PRIMARY KEY or suitable UNIQUE index, InnoDB internally generates a hidden clustered index named GEN_CLUST_INDEX on a synthetic column containing row ID values. The rows are ordered by the ID that InnoDB assigns to the rows in such a table. The row ID is a 6-byte field that increases monotonically as new rows are inserted. Thus, the rows ordered by the row ID are physically in insertion order. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2018, 04:02 |
|
||
|
Вопросы после переноса таблицы с MyISAM на InnoDB
|
|||
|---|---|---|---|
|
#18+
DDL исходной таблицы выглядит так: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. miksoftесли нет явно назначенного первичного ключа или подходящего уникальногоСправедливости ради, на той же странице чуть выше сказано: https://dev.mysql.com/doc/refman/8.0/en/innodb-index-types.html If you do not define a PRIMARY KEY for your table, MySQL locates the first UNIQUE index where all the key columns are NOT NULL and InnoDB uses it as the clustered index.Такой индекс есть. Как я писал в первом посте, все поля NOT NULL и в следующем посте упомянул об уникальном составном индексе. Другое дело, что движок не смог использовать этот индекс (в него входят не все поля таблицы) для нумерации строк и создал дополнительное поле. Тогда, если 6 байт помножить на 16384529 строк, получается 98307174 байт (чуть менее 100 МБ) на это скрытое дополнительное поле данных. Индексами таблица обвешана изрядненько, их аж 7 штук. Тогда получаем прибавку без малого в 0,8 гиг на всю таблицу. Оно немного не дотягивает до озвученной разницы в 1,2 гига, но остальные 0,3 гига вполне могут сожрать налоги накладные расходы. Тогда следующий вопрос. Как можно убедиться в существовании этого дополнительного поля и индекса в новой таблице? И это всё не вполне объясняет результат и разбухания и тормозов после ALTER TABLE. Хотя, если там происходила физическая перекладка записей, то можно ожидать и удвоение размеров. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2018, 10:31 |
|
||
|
Вопросы после переноса таблицы с MyISAM на InnoDB
|
|||
|---|---|---|---|
|
#18+
vkleДругое дело, что движок не смог использовать этот индекс (в него входят не все поля таблицы) для нумерации строк и создал дополнительное поле.Все и не должны входить. Так что индекс подходящий. Другое дело - UNIQUE KEY `key1` (`f1`,`f5`,`f7`,`f2`,`f3`) - это 4+5+1+3+4=17 байт Не помню какого размера указатель на строку в индексах MyISAM, но явно не больше 8 байт. А в InnoDB этот указатель превратится в 17 байт. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2018, 14:51 |
|
||
|
Вопросы после переноса таблицы с MyISAM на InnoDB
|
|||
|---|---|---|---|
|
#18+
miksoftТак что индекс подходящий.По описанию подходящий. И если дополнительное поле не было добавлено к таблице автоматически, тогда не вполне понятно, почему область данных потолстела на сотню с лишним мегабайт. На MyISAM: Данные 685.3 МБ Индекс 1.2 ГиБ На InnoDB после заливки дампа: Данные 920.8 МБ Индекс 2.2 ГиБ И нет ли смысла добавить в таблицу автоинкрементное поле с PRIMARY индексом с целью оптимизации размера? По размеру INT вполне достаточно, а это всего 4 байта. Для приложения такое поле не требуется вовсе. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2018, 19:34 |
|
||
|
Вопросы после переноса таблицы с MyISAM на InnoDB
|
|||
|---|---|---|---|
|
#18+
vkleИ нет ли смысла добавить в таблицу автоинкрементное поле с PRIMARY индексом с целью оптимизации размера? По размеру INT вполне достаточно, а это всего 4 байта. Для приложения такое поле не требуется вовсе.Надо считать и пробовать. Уменьшатся все индексы, но увеличится сама таблица и появится новый индекс, тот самый который (`f1`,`f5`,`f7`,`f2`,`f3`). Кроме того, все запросы, для которых используется этот индекс, станут дольше работать, т.к. индекс станет вторичным. И зачем нужен отдельный индекс по полю `f1`? По идее, для это роли достаточно индекса (`f1`,`f5`,`f7`,`f2`,`f3`). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.11.2018, 00:03 |
|
||
|
Вопросы после переноса таблицы с MyISAM на InnoDB
|
|||
|---|---|---|---|
|
#18+
miksoftИ зачем нужен отдельный индекс по полю `f1`? По идее, для это роли достаточно индекса (`f1`,`f5`,`f7`,`f2`,`f3`).Да тоже обратил на него внимание. Насколько помню в приложении, в нескольких запросах на выборку данная таблица по полю `f1` джойнится к другой таблице. Сходу не вспомню, есть ли какие-то другие причины на него ссылаться. miksoftвсе запросы, для которых используется этот индекс, станут дольше работать, т.к. индекс станет вторичнымСобственно, составной индекс используется лишь в одном месте, запрос INSERT ... ON DUPLICATE KEY UPDATE должен записать строку данных или обновить одно поле. Суть: извне приходит значение некоторого параметра и условия его получения, в таблице следует зафиксировать последнее полученное на текущую дату значение параметра в поле `f6` для списка условий, заданных в полях индекса. В сутки по статистике приходит максимум до сколько-то тысяч новых записей и всего до нескольких сотен записей на обновление. При таком раскладе время выполнения данного запроса возрастет как при добавлении, так и при обновлении записей, насколько понимаю. Запросы на выборку могут заработать быстрее за счет некоторой компенсации времени на просмотре более легкого индекса. Правильно понимаю? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.11.2018, 01:30 |
|
||
|
Вопросы после переноса таблицы с MyISAM на InnoDB
|
|||
|---|---|---|---|
|
#18+
vkleНасколько помню в приложении, в нескольких запросах на выборку данная таблица по полю `f1` джойнится к другой таблице. Сходу не вспомню, есть ли какие-то другие причины на него ссылаться.Если данная таблица ведущая, от джойну от индекса никакой пользы. Если ведомая, то, вероятно, и (`f1`,`f5`,`f7`,`f2`,`f3`) справится не сильно хуже, по крайней мере, если нет острого недостатка кэша индексов. vkleизвне приходит значение некоторого параметра и условия его получения, в таблице следует зафиксировать последнее полученное на текущую дату значение параметра в поле `f6` для списка условий, заданных в полях индекса. В сутки по статистике приходит максимум до сколько-то тысяч новых записей и всего до нескольких сотен записей на обновление. При таком раскладе время выполнения данного запроса возрастет как при добавлении, так и при обновлении записей, насколько понимаю.Да. vkleЗапросы на выборку могут заработать быстрее за счет некоторой компенсации времени на просмотре более легкого индекса.А вот тут надо пробовать. Начиная с с некоторой версии MySQL научился использовать для чтения данных те технические поля вторичного индекса, которые являются указателем на первичный индекс таблицы. Если этот эффект был задействован в каких-нибудь запросах и, одновременно, используемый индекс был для этого запроса покрывающим, то время выполнения таких запросов может возрасти. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.11.2018, 20:25 |
|
||
|
Вопросы после переноса таблицы с MyISAM на InnoDB
|
|||
|---|---|---|---|
|
#18+
vkle, Кстати, а OPTIMIZE TABLE меняет ситуацию после заливки данных в InnoDB ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.11.2018, 20:26 |
|
||
|
Вопросы после переноса таблицы с MyISAM на InnoDB
|
|||
|---|---|---|---|
|
#18+
miksoftКстати, а OPTIMIZE TABLE меняет ситуацию после заливки данных в InnoDB ?Хорошо, что напомнили, подумал и забыл проверить. Работало оно очень долго (порядка часу) и обрадовало: "Table does not support optimize, doing recreate + analyze instead". Обе таблицы, пришли к одному размеру в 3,3 гига - одна уменьшилась (после ALTER TABLE) с 5,7, другая увеличилась (заливка дампа) с 3,1. Количество строк в статистике тоже изменилось, стало заметно ближе к реальному значению - теперь ошибка порядка 50 тысяч против нескольких сотен тысяч сразу после преобразования. Знак ошибки сохранился. Время выполнения SELECT COUNT(1) стало одинаковым, порядка 10 секунд. miksoftЕсли ведомая, то, вероятно, и (`f1`,`f5`,`f7`,`f2`,`f3`) справится не сильно хуже, по крайней мере, если нет острого недостатка кэша индексов.Ведомая она. Вообще, надо посмотреть планы тех запросов, который индекс из двух они используют реально. По остальным вопросам вполне понятно. Конечно, ситуация после ALTER TABLE стала ещё тем сюрпризом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2018, 10:30 |
|
||
|
Вопросы после переноса таблицы с MyISAM на InnoDB
|
|||
|---|---|---|---|
|
#18+
vkleи обрадовало: "Table does not support optimize, doing recreate + analyze instead"для InnoDB это нормально, там оптимизация делается именно так. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2018, 10:44 |
|
||
|
Вопросы после переноса таблицы с MyISAM на InnoDB
|
|||
|---|---|---|---|
|
#18+
Почти оффтоп. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2018, 12:41 |
|
||
|
Вопросы после переноса таблицы с MyISAM на InnoDB
|
|||
|---|---|---|---|
|
#18+
Почти оффтоп. Установил версию 8.0.13 есть там MyISAM и Merge. Но также слышал, что MyISAM не должен там быть. vkle> Скажите, сто с SELECT COUNT(1) ... у вас получилось ? 3min - трэш какой-то. У меня похожего размера база и также думаю о переходе на InnoDB. Спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2018, 12:47 |
|
||
|
Вопросы после переноса таблицы с MyISAM на InnoDB
|
|||
|---|---|---|---|
|
#18+
Fitter2vkle> Скажите, сто с SELECT COUNT(1) ... у вас получилось ? 3min - трэш какой-то.Прочтите внимательно, в инструкции есть два способа переноса таблицы на InnoDB. Один способ дал на выходе проблемную таблицу, другой - нормальную. К тому же, проблема имеет место конкретно в моем случае (на сервере версии 5.7, DDL см. выше). Иначе вряд ли этот способ был бы официально рекомендован. Вполне возможно, что на 8.0 и с другой структурой исходной таблицы результат будет, как минимум, не столь ужасен. Кроме того, прямо сейчас у меня нет необходимости в смене движка. Конечно, рано или поздно переезжать придется. Не факт, что именно в таком направлении. Тем не менее, я лишь решил заранее протестировать переезд, чтобы потом в боевой обстановке понятно было, что можно ожидать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2018, 21:16 |
|
||
|
Вопросы после переноса таблицы с MyISAM на InnoDB
|
|||
|---|---|---|---|
|
#18+
У меня есть небольшая мысль для ускорения. Что если устнавить Мастер - Слэйв, а перед ними hapoxy для деления Read\Write и на Мастере использовать InnoDB, а на Слэйве MyISAM. Или может кто тестил так, поделитесь впечатлениями? Спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2018, 22:31 |
|
||
|
Вопросы после переноса таблицы с MyISAM на InnoDB
|
|||
|---|---|---|---|
|
#18+
Fitter2на Мастере использовать InnoDB, а на Слэйве MyISAM.А это в принципе возможно? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2018, 22:33 |
|
||
|
Вопросы после переноса таблицы с MyISAM на InnoDB
|
|||
|---|---|---|---|
|
#18+
автор1 row in set (3 min 28.29 sec) Опс... Три минуты!!! Повторно делаю тот же запрос, и спустя много времени ещё - аналогично, менее 3 минут ни разу не отработал. myIsam возвращает счетчик из заголовка. InnoDb сканирует таблицу из-за версионности ибо не знает какие записи сейчас видны считающей транзакции. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.11.2018, 11:23 |
|
||
|
Вопросы после переноса таблицы с MyISAM на InnoDB
|
|||
|---|---|---|---|
|
#18+
miksoftFitter2на Мастере использовать InnoDB, а на Слэйве MyISAM.А это в принципе возможно? для statement based replication точно да. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.11.2018, 11:24 |
|
||
|
Вопросы после переноса таблицы с MyISAM на InnoDB
|
|||
|---|---|---|---|
|
#18+
По ману вроде и row сработает: https://dev.mysql.com/doc/refman/8.0/en/replication-solutions-diffengines.html ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.11.2018, 01:37 |
|
||
|
|

start [/forum/topic.php?fid=47&msg=39734695&tid=1829462]: |
0ms |
get settings: |
9ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
44ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
51ms |
get tp. blocked users: |
1ms |
| others: | 13ms |
| total: | 148ms |

| 0 / 0 |

Извините, этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
... ля, ля, ля ...