Какие индексы следует добавить, чтобы ускорить запросы к массивной таблице InnoDB?

#mysql #optimization #indexing

#mysql #оптимизация #индексирование

Вопрос:

Вот моя таблица:

 CREATE TABLE `letters` (
  `a` bigint(20) unsigned NOT NULL,
  `b` bigint(20) unsigned NOT NULL,
  `c` bigint(20) unsigned NOT NULL,
  `d` bigint(20) unsigned NOT NULL,
  `e` bigint(20) unsigned NOT NULL,
  PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8$$
  
  • В таблице будет около 1 миллиарда строк.
  • Можно запрашивать каждый столбец; на каждый столбец можно ссылаться. например:
    • ВЫБЕРИТЕ [любой столбец] ИЗ букв, ГДЕ [любой / любой другой столбец] В ([подзапрос или список]);

Мой вопрос: какие индексы я должен добавить, чтобы ускорить любой запрос в приведенном выше формате? (Также, если возможно, пожалуйста, попробуйте описать, «почему» это / они должны быть добавлены, чтобы я мог извлечь уроки из вашего ответа).

Спасибо!

— Дополнительная информация: вставки будут происходить довольно регулярно (несколько / несколько раз в секунду), но запросы select будут выполняться чаще.

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

1. Вы действительно не предоставили ничего, что можно было бы продолжить, не уточнив ваши общие запросы.

2. Вместо того, чтобы перечислять каждую возможность запроса, я предоставил шаблон всех запросов. Предположим, что каждый столбец может входить в каждый пробел. Вот почему я задаю вопрос, это не просто: используйте этот индекс, потому что ваши запросы склоняются к нему. — Нет «общих запросов». Это равномерное распределение указанного шаблона.

3. Вы могли бы разделить таблицу по столбцу ‘e’, а затем настроить индексы для b-d

4. Не имеет значения. ГДЕ e = 1 — это избирательность, а не распределение значений e по другим перестановкам столбцов. Если вы сделали, ГДЕ a = 42 и e = 1, тогда да, это имеет значение.

5. Если бы запрос не включал предикат на ‘e’, тогда, да, скорее всего, были бы некоторые дополнительные накладные расходы при объединении результатов из нескольких разделов. В идеале разбиение (и ничто не мешает вам разбивать разделы на любые другие столбцы, кстати) должно основываться на наиболее часто используемом столбце предикатов (где a =, где b =, где c = и т. Д. И т. Д.). Еще одна вещь, на которую вы могли бы обратить внимание, — действительно ли вам нужны все данные. Можно ли что-нибудь из этого заархивировать, чтобы уменьшить объемы данных и, следовательно, ускорить выполнение любых запросов? Удачи вам!

Ответ №1:

Поскольку в предложении WHERE может появиться любой столбец, вы должны добавить индекс для каждого столбца, за исключением поля a, поскольку оно уже является ПЕРВИЧНЫМ КЛЮЧОМ и, как таковое, уже проиндексировано.

ОБНОВЛЕНИЕ: что касается последующего обсуждения, Poodlehat указал, что столбец e имеет низкую избирательность индекса, т. Е. «Отношение количества различных значений в индексированном столбце / столбцах к количеству записей в таблице». По этой причине неясно, поможет ли добавление индекса в столбец e или замедлит запросы. Итак, Лукас попробует экспериментально и, надеюсь, поделится с нами результатами.

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

1. Это то, что, по моему мнению, следует сделать, но будет ли иметь один индекс в каждом столбце намного быстрее, чем отсутствие индексов (кроме PK)? Я знаю, что мне не следует добавлять составные индексы для каждой пары 2, потому что тогда мои вставки будут длиться вечно.

2. Плохая идея добавлять индекс к столбцам с плохой избирательностью.

3. Вы правы, но, предполагая, что 15 значений столбца e распределены равномерно, это означает 6,66% — В этом документе об Oracle , но это общее руководство, говорится: мы должны создавать индексы для таблиц, которые часто запрашиваются для менее чем 15% строк таблицы.

4. @stivlo — К сожалению, вы не можете предположить равномерное распределение. Вероятно, будут случаи, когда одно значение ‘e’ приведет к 20% результатов, еще 15%, еще 10%, а остальные .. меньше%.

5. @Lucas, да, возможно, поэтому, возможно, он мог бы попробовать с индексом в столбце e и без него и посмотреть, что работает быстрее.

Ответ №2:

Я думаю, вам нужно иметь уникальный индекс a (или это должен быть первичный ключ), определенно индексы b,c,d (для каждого). Нет необходимости в индексации e (он все равно не будет использоваться, поскольку, как вы говорите, он имеет всего 15 разных значений)