Два одноколоночных индекса против одного двухколоночного индекса в MySQL? - PullRequest
93 голосов
/ 28 февраля 2010

Я столкнулся со следующим, и я не уверен, что лучше всего практиковать.

Рассмотрим следующую таблицу (которая станет большой):

id PK | giver_id FK | receient_id FK | дата

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

SELECT...WHERE giver_id = x AND recipient_id = t.

Каждая такая комбинация будет уникальной в таблице.

Есть ли какая-либо выгода от добавления двухколоночного индекса к этим столбцам, или двух теоретических индексов в теории будет достаточно / одинаково?

Ответы [ 4 ]

110 голосов
/ 28 февраля 2010

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

Если у вас есть индекс с двумя столбцами, запрос может быть быстрее (вы должны измерить). Индекс из двух столбцов также может использоваться как индекс одного столбца, но только для столбца, указанного первым.

Иногда бывает полезно иметь индекс для (A, B) и другой индекс для (B). Это делает запросы, использующие один или оба столбца быстрыми, но, конечно, также использует больше дискового пространства.

При выборе индексов вам также необходимо учитывать влияние на вставку, удаление и обновление. Больше индексов = медленные обновления.

25 голосов
/ 28 февраля 2010

Индекс покрытия типа:

ALTER TABLE your_table ADD INDEX (giver_id, recipient_id);

... будет означать, что индекс может использоваться, если запрос ссылается на giver_id или комбинацию giver_id и recipient_id. Помните, что критерии индекса основаны на крайнем левом значении - запрос, ссылающийся только на recipient_id, не сможет использовать индекс покрытия в предоставленной мной инструкции.

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

4 голосов
/ 28 февраля 2010

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

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

1 голос
/ 26 мая 2017

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

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