Один составной индекс или много индексов для внешних ключей? - PullRequest
0 голосов
/ 18 мая 2018

В чем разница между созданием индекса покрытия для всех внешних ключей таблицы отношений и созданием одного индекса для каждого столбца (внешнего ключа) таблицы отношений?

Например, у меня есть таблицаsales(p_id, e_id, c_id, ammount) где p_id - внешний ключ (таблица продуктов), e_id - внешний ключ (таблица сотрудников) и c_id - внешний ключ (customer_table).Первичный ключ таблицы - {p_id, e_id, c_id}.Что лучше?

CREATE INDEX cmpindex ON sales(p_id, e_id, c_id)

ИЛИ

CREATE INDEX pindex on sales(p_id)
CREATE INDEX eindex on sales(e_id)
CREATE INDEX cindex on sales(c_id)

В основном я выполняю запросы с объединениями в таблице отношений и родительских таблицах.

Ответы [ 5 ]

0 голосов
/ 23 января 2019

Обратите внимание, что индекс составного ключа будет использоваться только в том случае, если вы запрашиваете первую часть, первую и вторую части, первую, вторую и третью части и т. Д., Поэтому запрашиваете p_id или p_id и e_id и т. Д.или даже e_id и p_id будут использовать индекс.Действительно, любой запрос, содержащий p_id, будет использовать этот индекс.Однако, если вы запросите таблицу продаж по e_id или c-id или по любой их комбинации, cmpindex не будет использован, и будет выполнено полное сканирование таблицы.

Одно преимущество - наличие индекса для каждого внешнегоключ (неуникальный индекс, поскольку может быть несколько продаж одного и того же продукта, или одним и тем же сотрудником, или одному и тому же клиенту, что приводит к дублированию записей в индексе), заключается в том, что оптимизатор запросов может использоватьиндекс, чтобы уменьшить количество возвращаемых строк, а затем выполнить последовательный поиск по набору результатов.

Например, если запрос представляет собой поиск продаж определенного продукта конкретному клиенту (независимо от сотрудника) и выПри наличии миллиона продаж индекс Cindex по внешнему ключу можно было бы использовать для возврата 20 единиц продаж данному конкретному клиенту, и этот набор результатов можно было бы очень эффективно последовательно искать, чтобы определить, какие из этих продаж были для определенного продукта.Если поиск был выполнен по продукту и использовался pindex, результирующий набор может составлять 10 000 строк (все продажи этого продукта), которые необходимо будет последовательно искать, чтобы найти продажи этого продукта конкретному покупателю, что приведет к оченьнеэффективный запрос.

Я считаю, что статистика, хранящаяся для таблицы (используемой оптимизатором), отслеживает среднее количество строк, которые будут возвращены для запроса с использованием каждого индекса, поэтому оптимизатор сможетВыясните, что в приведенных выше примерах следует использовать cindex, а не pindex.Кроме того, вы можете дать подсказки в ваших запросах, чтобы указать, какой конкретный индекс будет использоваться.Очевидно, что важно запускать UPDATE STATISTICS на регулярной основе, поскольку план выполнения будет использовать pindex в приведенном выше примере, если в среднем будет только 10 продаж каждого продукта.

0 голосов
/ 18 мая 2018

В других ответах отсутствует важный момент.Когда вы объявляете внешний ключ в MySQL, он создает индекс для столбца.Это не обязательно (обязательно) верно в других базах данных, но верно в MySQL.

Итак, объявление автоматически создает следующие индексы:

CREATE INDEX pindex on sales(p_id);
CREATE INDEX eindex on sales(e_id);
CREATE INDEX cindex on sales(c_id);

(Эти индексы очень удобны для работыс каскадными ограничениями и поддержанием целостности данных на основе внешнего ключа.)

Если вы также объявили индекс на sales(p_id, e_id, c_id, amount), то первый из индексов не нужен - это подмножествоэтого индекса.Однако нужны два других.

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

0 голосов
/ 18 мая 2018

Как прокомментировал HoneyBadger, у вас уже есть составной индекс, поскольку ваш первичный ключ сам по себе является индексом.

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

Как указано здесь , когда у вас есть составной индекс, он может работать с запросами, включающими все поля, или с запросами, включающими первое поле (по порядку), первоеи второй, или первый, второй и третий вместе.Он не будет использоваться в запросах, включающих только второе и третье поле.

0 голосов
/ 18 мая 2018

Какой из них лучше, зависит от ваших реальных запросов.

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

Если вы присоединяете таблицу sales всегда ко всем трем другим таблицам (customer, product и employee) тогда предпочтительнее будет составной индекс, если предположить, что механизм фактически его использует и не будет выполнять сканирование таблицы.

Порядок полей в составном индексе важен, когда речь идет о порядкеРезультаты.Например, если ваш запрос собирается сгруппировать результаты по продукту (сначала), а затем заказать детали по каждому клиенту, вы можете воспользоваться индексом, в котором сначала указан идентификатор продукта, а во втором - идентификатор клиента.

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

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

Если у вас есть только один запрос к таблице sales, вам не нужно иметь несколько индексов.Но, скорее всего, у вас есть несколько запросов, которые выдают совершенно разные результаты, с различными вариантами выбора полей, фильтрами, группировками и т. Д.запроса и другие для других.Обратите внимание, что то, что вы предлагаете, не является взаимоисключающим.Возможно, вы могли бы извлечь выгоду из нескольких составных индексов, которые просто имеют другой порядок полей.

Очевидно, что множество индексов будет замедлять изменения данных в этих таблицах, поэтому вам необходимо учитывать и этот компромисс.

0 голосов
/ 18 мая 2018

Если ваши запросы (поиск) распространяются через продажи для каждой из таблиц независимо, то вы должны создать отдельный индекс для каждой из них.Если в этом нет необходимости, вы можете пойти на композит.

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