Подтвердить что ты не робот

Является ли индекс на A, B избыточным, если есть индекс на A, B, C?

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

Используя SQL Server, если у меня есть таблица с индексом в столбце A и столбце B, а второй индекс столбцов A, B и C, было бы безопасно отказаться от первого индекса, так как второй индекс в основном будет удовлетворять запросам, которые выиграют от первого индекса?

4b9b3361

Ответ 1

Это зависит, но ответ часто "Да, вы можете отбросить индекс на (A, B)".

Контр-случай (где вы не должны отбрасывать индекс (A, B)), когда индекс на (A, B) является уникальным индексом, который обеспечивает ограничение; то вы не хотите отбрасывать индекс (A, B). Индекс на (A, B, C) также может быть уникальным, но уникальность избыточна, потому что комбинация (A, B) уникальна из-за другого индекса.

Но при отсутствии таких необычных случаев (например, если оба (A, B) и (A, B, C) позволяют дублировать записи), то индекс (A, B) логически избыточен. Однако, если столбец C является "широким" (a CHAR (100) столбец, возможно), тогда как A и B малы (скажем, INTEGER), тогда индекс (A, B) более эффективен, чем (A, B, C), потому что вы можете получить больше информации, прочитанной на странице индекса (A, B). Таким образом, хотя (A, B) является избыточным, его можно сохранить. Вам также необходимо учитывать волатильность таблицы; если таблица редко изменяется, дополнительные индексы не имеют большого значения; если таблица сильно изменится, дополнительные индексы замедляют внесение изменений в таблицу. Не сложно ли это угадать; вам, вероятно, потребуется выполнить измерения производительности.

Ответ 2

Первый индекс охватывает запросы, которые просматриваются на A, A,B, а второй индекс может использоваться для покрытия запросов, которые выглядят на A, A,B или A,B,C, что явно является надмножеством первый случай.

Если C очень широкий, однако индекс на A,B может быть полезен, так как он может удовлетворять определенным запросам с меньшим количеством чтений.

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

SELECT a,b
FROM YourTable
ORDER BY a,b

Ответ 3

Да, это обычная оптимизация. Любой запрос, который будет полезен для индекса на A, B, также может быть полезен также из индекса на A, B, C.

В сообществе MySQL существует даже инструмент для поиска всей схемы для избыточных индексов: http://www.percona.com/doc/percona-toolkit/pt-duplicate-key-checker.html

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

Ответ 4

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

Если первый индекс сделан A desc, B asc и второй A asc, B asc, C asc, то удаление его первого индекса на самом деле не способ, потому что второй не является надмножеством первого, и ваш запрос не может пользуйтесь вторым индексом, если упорядочение записано в первом.

В некоторых случаях, например, когда вы используете первый индекс, вы можете order by A desc, B asc (конечно) и A asc, B desc, но вы также можете сделать запрос, который будет использовать любую часть этого индекса, например Order by A desc.

Но такой запрос, как order by A asc, B asc, не будет "покрыт" первым индексом.

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

Ответ 5

Я обычно нашел бы этот "почти" аналогичный индекс в таблице, содержащий исторические данные. Если column C - это дата или целочисленный столбец, будьте осторожны. Скорее всего, это используется для удовлетворения функции MAX, как в WHERE tblA.C = MAX(tblB.C), которая полностью пропускает таблицу и использует только путь доступа только к индексу.