Несколько индексных личностей: Пограничные дубликаты ключей

#sql #sql-server #database #indexing #non-clustered-index

Вопрос:

Я запускаю sp_BlitzIndex от Брента Озара и получаю несколько таких предметов.

 Multiple Index Personalities: Borderline duplicate keys
 

Я не знаю на 100% , что делать, но вот пример ниже.

 CREATE INDEX [IX_Test] ON [Test] ( [SportId] ) WITH (FILLFACTOR=100, ONLINE=?, SORT_IN_TEMPDB=?, DATA_COMPRESSION=?);

CREATE UNIQUE INDEX [IX_Test_2] ON [Test] ( [SportId], [AnotherId] ) WITH (FILLFACTOR=100, ONLINE=?, SORT_IN_TEMPDB=?, DATA_COMPRESSION=?);
 

Как вы можете видеть, они кажутся похожими. Мой вопрос в том, больно ли удалять первый спортивный индекс, но сохранять двойной индекс (спортивный, текстовый).

Каков мой лучший подход здесь?

Комментарии:

1. Сохранение второго индекса имеет смысл, первый может быть выбран некоторыми запросами, поскольку он немного уже, но добавление предположительно одного столбца int не должно иметь значения. Проверьте sys.dm_db_index_usage_stats , как каждый из них используется в настоящее время.

2. Я бы предложил удалить первый индекс. Это излишне со вторым.

3. Можете ли вы дать ответ и указать, почему он избыточен?

Ответ №1:

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

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

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

Комментарии:

1. Как только более широкий из них окажется в «памяти»/плане/»кэше», SQL никогда не загрузит первый. Это просто вносит путаницу в общую картину.

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