2010-02-28 2 views
65

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

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

ID PK | giver_id FK | recipient_id FK | date

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

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

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

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

ответ

76

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

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

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

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

21

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

ALTER TABLE your_table ADD INDEX (giver_id, recipient_id); 

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

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

+4

'MySQL может использовать только один индекс для SELECT', это уже не так, было бы неплохо, если вы отредактировали свой ответ для обновления. – Davor

+0

Не могли бы вы объяснить, почему индекс покрытия не сможет использоваться 'recipient_id'? –

+2

@IvoPereira Множественные индексы столбцов в MySQL позволяют использовать все поля в индексе слева направо. Например, если у вас есть 'INDEX (col1, col2, col3, col4)', тогда индекс будет применяться для поиска с предложением WHERE, например 'col1 = 'A'' или' col1 =' A 'AND col2 = 'B' 'или' col1 = 'A' AND col2 = 'B' AND col3 = 'C' AND col4 = 'D'', но этот конкретный индекс не будет использоваться ни для чего, как' WHERE col2 =' B ' 'или' WHERE col3 = 'C' AND col4 = 'D'', потому что поля поиска больше не указаны в определении индекса. Вам нужно будет добавить дополнительные индексы для охвата этих полей. – Slicktrick

3

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

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

+0

Спасибо, Марк, один из ключей действительно очень избирательный, так что все должно быть хорошо. Я решил сохранить два (автоматических) индекса на месте и посмотреть, как он работает с течением времени. Я также подумал о комбинированном получателе: первичный ключ получателя, но так как каждое поле также должно быть доступно для поиска по отдельности, оно просто добавит накладные расходы php. Кроме того, новый ключ будет (более длинной) строкой вместо (короче) целого числа. – Tom

0

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

Смежные вопросы