Страницы

Поиск по вопросам

вторник, 9 июля 2019 г.

Большая MYSQL таблица (более 200 000 000 записей). Как расставить индексы?

Есть большая (на мой взгляд) MYSQL таблица (19 полей). Даже запрос SELECT COUNT(*) FROM table_name; выполняется 6 минут, что меня не очень устраивает. Нужно расставить индексы так, чтобы не испортить дела окончательно и быстро производить выборки по нескольким определенным полям (примерно 5-7 из 19). Можно ли добавлять индексы к уже заполненной таблице, и сколько по времени это будет происходить?


Ответ

Добавление индекса на большой табличке
Добавить индекс можно всегда. Вопрос в том, что при этом произойдёт постороннего. В зависимости от storage engine и версии СУБД.
mysql/innodb до 5.6 при добавлении индекса заблокируют таблицу на запись. Т.е. все insert, update, delete запросы будут ждать окончание создания индекса. select работать сможет. Начиная с 5.6 - создание индекса возможно конкурентное.
Если вы на старой версии - то классический трюк был поднять репликацию, затем на слейве создать индекс, подождать, пока слейв догонит мастер, переключить слейв в новый мастер. Этот же трюк должен получиться с любым storage engine.
Сколько времени займёт создание индекса - в зависимости от объёма данных и железки, на которой крутится mysql
count
Просто не используйте count на больших наборах строк. Для аналитики - считайте отдельно. Для тяжёлой аналитики нормальное решение - отдельная железка с репликацией базы только для запросов расчёта аналитики.
Или считать count'ы отдельно, редисом, или колоночными субд. Или триггерами, если читать количество надо гораздо чаще, чем писать.
как расставить индексы
Нужно изучать конкретное приложение. Универсального ничего сказать нельзя.
Что вообще делать с большой табличкой
У mysql из коробки есть поддержка партицирования. Некоторые ограничения есть по использованию, например не поддерживаются foreign keys. Как правило, почти все запросы от приложения к большим табличкам имеют под собой какой-то общий фильтр. Например, 90% запросов хотят данные только за последний месяц, или почти всегда привязаны к id пользователя. Возможно, данные в вашей табличке можно порезать на партиции.

Комментариев нет:

Отправить комментарий