Нужно ли иметь индекс для каждой комбинации запрашиваемых полей в таблице SQL, чтобы оптимизировать производительность? - PullRequest
7 голосов
/ 28 июля 2011

Если в моей таблице User есть несколько полей для запроса (скажем, DepartmentId, GroupId, RoleId), будет ли разница в скорости, если я создам индекс для каждой комбинации этих полей?

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

В данный момент у меня есть индекс для DepartmentId, GroupIdи RoleId.Это один неуникальный индекс для каждого поля.

Если конечный пользователь выбирает «кого-либо в группе B», SQL выглядит так:

select * from User where GroupId = 2

Наличие индекса для GroupId должно ускоритьup.

Но если конечный пользователь выберет «любой в группе B и в роли C», SQL будет выглядеть так:

select * from User where GroupId = 2 and RoleId = 3

Индексы для GroupId и RoleId по отдельности могут нечто-то меняет, верно?

Лучший индекс для этого поиска был бы, если бы у меня был один индекс, охватывающий и GroupId и RoleId.

Но если это так, чемэто означало бы, что мне понадобится индекс для каждой комбинации запрашиваемых полей.Поэтому мне понадобятся все эти индексы:

  • DepartmentId
  • GroupId
  • RoleId
  • DepartmentId и GroupId
  • DepartmentId и RoleId
  • GroupId и RoleId
  • Department Id, GroupId и RoleId

Может кто-нибудь пролить свет на это?Я использую MySQL, если это имеет значение.

Ответы [ 6 ]

8 голосов
/ 28 июля 2011

Многостолбцовый индекс может использоваться для любого левого префикса этого индекса. Таким образом, индекс на (A, B, C) можно использовать для запросов на (A), (A, B) и (A, B, C), но его нельзя, например, использовать для запросов на (B) ) или (B, C).

Если все столбцы индексируются индивидуально, MySQL (5.0 или более поздняя версия) также может использовать Оптимизация слияния индексов .

3 голосов
/ 28 июля 2011

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

Эффективность индексов зависит от:

  • Процент SELECTs против INSERTs и UPDATEs
  • Особенности запросов SELECT и их использование JOIN
  • Размер индексируемой таблицы
  • ОЗУ и скорость процессора
  • Настройки MySQL для определения объема используемой оперативной памяти и т. Д.

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

2 голосов
/ 28 июля 2011

Тщательно создавайте индексы! Я бы предложил собрать статистику запросов и решить, какой столбец чаще используется во время поиска, чтобы вы могли создать кластеризованный индекс для этого конкретного столбца (в любом случае, когда вы создаете индекс по нескольким столбцам - физически данные можно упорядочить только по одному столбцу)

Также имейте в виду, что кластеризованный индекс может значительно снизить производительность запросов UPDATE/INSERT/DELETE, поскольку это приводит к переупорядочению физических данных.

2 голосов
/ 28 июля 2011

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

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

1 голос
/ 28 июля 2011

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

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

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

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

0 голосов
/ 28 июля 2011

Удалите все индексы и запустите операторы CRUD для таблицы, используя бесплатный инструмент под названием «SQL sentry plan explorer».

Он покажет вам, какие индексы необходимы.

Индексы создаются на основе CRUD, а не на самой таблице.

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