оптимизация таблицы mysql с записями 1,5 м, большинство из которых были удалены - PullRequest
1 голос
/ 02 февраля 2020

У меня есть таблица MySQL, которая содержит около 1,5 миллионов записей, и размер таблицы составляет 1,3 ГБ

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

Из этих 1,5 миллиона записей только 30 КБ не удаляются программно. это означает, что к ним часто обращаются, в то время как другие записи почти не доступны, но в некоторых случаях они есть.

Таким образом, эта таблица интенсивно используется и запрашивается для не удаленных записей, а иногда для мягко удаленных записей. .

У меня есть индексный тип BTREE для записи deleted_at (с числом элементов 35К). Таблица становится тяжелее со временем и, очевидно, это не масштабируемое решение.

Двигатель стола - MyISAM. большинство других таблиц - InnoDB, но эта таблица часто запрашивается с STORED PROCEDURE, и когда я изменил на InnoDB, запросы были намного медленнее.

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

Вещи, о которых я думал:

  • разбиение, но Я не могу использовать partitions, так как некоторые столбцы проиндексированы FULL TEXT.
  • разбить данные на две таблицы. один для удаленных строк и один для не удаленных строк, к которым часто обращаются и запрашивают. это изменение требует значительных изменений инфраструктуры, поэтому я не спешу это делать.
  • создаю новую таблицу, которая будет синхронизировать c с исходной таблицей один раз в 10 / 20мин вместо разделения и будет содержать только не удаленные строки. это потребует небольших изменений инфраструктуры, а обслуживание намного проще и безопаснее. разбиение на две таблицы может привести к отсутствию записей из-за сбоев запросов, поскольку операция «УДАЛИТЬ» фактически переместит строку из одной таблицы в другую и, следовательно, требует сложного механизма

Какие еще варианты у меня есть? я могу дать приоритет некоторым строкам в таблице с MySQL? Память мудрая.

У меня есть 10.3.20-MariaDB и 32 ГБ оперативной памяти

1 Ответ

3 голосов
/ 02 февраля 2020

MyISAM не кэширует строки, он только кэширует индексы. Для буферизации строк он использует кеш файловой системы.

Таким образом, вы можете убедиться, что индекс полностью загружен в кэш:

  1. Увеличьте key_buffer_size, чтобы он был как минимум размером с ваши индексы MyISAM для этой таблицы. Используйте SHOW TABLE STATUS, чтобы узнать размер индекса.
  2. Если у вас несколько таблиц MyISAM, вам может потребоваться выделить кэш ключей специально для этой таблицы. См. ИНДЕКС CACHE .
  3. Предварительная загрузка индекса в кэш ключей при запуске. См. ИНДЕКС ЗАГРУЗКИ В КЭШ * .

Вы также можете рассмотреть возможность использования многостолбцовых индексов с учетом ваших запросов. Например, если у вас есть запрос WHERE user_id = 1234 AND deleted_at IS NULL, вы должны создать индекс для (user_id, deleted_at).

Какие индексы вам нужны, зависит от запросов, которые вы хотите оптимизировать.

Честно говоря, я бы разбил таблицу так, чтобы удаленные строки находились во второй таблице. Это уменьшит размер вашей таблицы на 98%, и это может сделать запросы достаточно быстрыми, чтобы вам больше не приходилось использовать MyISAM.

...