Последствия использования уникального некластерного индекса с покрывающими столбцами вместо первичного ключа

12

У нас есть большая таблица, в [MyTable]которой в настоящее время есть и a Primary Key, и a Unique Non Clustered Indexв одном столбце ( [KeyColumn]). Индекс U NC также имеет дополнительные столбцы покрытия.

Наличие как PK, так и Unique NC Index в одних и тех же столбцах представляется избыточным, поэтому я рассмотрел вопрос об удалении первичного ключа и использовании вместо этого уникального некластеризованного индекса для целей ссылочной целостности.

Обратите внимание, что таблица полностью кластеризована другим столбцом.

То есть так имеем:

ALTER TABLE [MyTable]
    ADD CONSTRAINT [PK_MyTable] 
    PRIMARY KEY NONCLUSTERED ([KeyColumn])
GO

И

CREATE UNIQUE NONCLUSTERED INDEX [IX_MyTable_SomeIndex] 
    ON [MyTable] ([KeyColumn]) 
    INCLUDE ([Column1], [Column2])
GO

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

  • Отбросьте ограничения внешнего ключа, зависящие от MyTable.KeyColumn
  • Оставьте Первичный Ключ MyTable.KeyColumnполностью
  • Повторно добавьте внешние ключи в таблицу (т.е. RI будет принудительно введен через MyTable.KeyColumn)

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

Я прочитал /programming/487314/primary-key-or-unique-index и доволен аспектами целостности и производительности.

Мой вопрос: является ли этот подход некорректным?

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

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

StuartLC
источник
Не могли бы вы прокомментировать, что вы пытаетесь достичь? Вы также должны убедиться, что в итоге вы получите кластеризованный индекс.
@ jn29098 - Обновлено. Подтверждено, что у нас есть кластеризованный индекс для столбцов, которые не являются ни PK, ни покрывающими столбцами, так что это не имеет отношения к этому решению.
StuartLC
1
Вы уверены, что у вас нет какого-либо инструмента / ORM / инструмента моделирования генерации данных, который будет раздражать, когда он увидит, что ПК нет?
Ремус Русану
Единственный недостаток, который я вижу, состоит в том, что после того, как PK исчезнет ... тогда у вас есть только один индекс для ключевого столбца, и запросы, использующие PK-индекс, скажем, для сканирования индекса по ключевому столбцу или упорядочения по ключевым столбцам и не охваченные индексом Uniuqe, могут вызвать несколько дополнительных операций ввода-вывода. так как уникальные индексные листовые страницы намного больше, чем у PK. Иначе это выглядит хорошо. Но некоторые пуристы скажут, что у вас должен быть PK :)
Gulli Meel
1
Я бы посоветовал вам проверить полезность этого индекса, используя статистику использования индекса DMV, и посмотреть, используется ли он некоторыми вашими запросами. Проверьте его по уникальному ключевому индексу, а затем определите, что произойдет с запросом, использующим этот запрос. index ..
Gulli Meel

Ответы:

3

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

Вы должны быть в состоянии доказать, что то, что предложено, действительно поможет (стоимость против выгоды). По какой причине рассматривается это изменение? Есть ли на самом деле проблемы с производительностью этой таблицы, или она просто "выглядела неправильно"?

Вот некоторые другие вопросы, которые помогут вам прийти к лучшему решению для вашей среды:

  • Сколько времени будет сэкономлено в окне обслуживания? В окне резервного копирования?

  • Какой объем памяти это сэкономит (файлы данных, файлы журналов, резервные копии и т. Д.)?

  • Является ли INSERTпроизводительность на этом столе действительно узким местом прямо сейчас? Насколько это улучшится? Является ли удаление индекса лучшей стратегией для решения этой проблемы?

  • Не вызовет ли это проблемы с инструментами и структурами баз данных (особенно ORM), которые ожидают, что у каждой таблицы будет первичный ключ, а не только уникальный индекс? Для репликации транзакций требуется первичный ключ в опубликованных таблицах.

  • Важна ли схема самодокументируемой базы данных?

  • Несмотря на ограниченное использование, узость индекса первичного ключа все еще позволяет оптимизатору создавать более эффективные планы для определенных запросов? (Используйте, sys.dm_db_index_usage_statsчтобы узнать.)

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

Джон Сайгель
источник
Спасибо - получается, что статистика индекса показала, что ПК все еще активно использовался для сканирования. Кажется, я переусердствовал - преимущества сохранения читаемости / условных обозначений при сохранении PK должны перевешивать любые последствия для хранилища в долгосрочной перспективе. Дело в том, что репликация транзакций подтверждает это - нам нужно будет вскоре скопировать эту базу данных.
StuartLC
2

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

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

Пока вы заботитесь об обнуляемом аспекте, с одним индексом у вас все будет в порядке.

Если бы это была моя БД, я бы, наверное, выбрал один уникальный индекс, при прочих равных условиях.

Мэтт Уитфилд
источник
Спасибо - у вас есть ссылки? Несколько хуже, вы имеете в виду только более низкую плотность индекса в индексе покрытия или есть что-то еще, что могло бы вызвать это?
StuartLC
К сожалению, это просто из большого опыта и общения с людьми намного умнее меня за эти годы! И да, это именно так - будет меньше строк на странице, поэтому больше ввода / вывода. Однако стоит отметить, что столбцы INCLUDE присутствуют только на уровне листьев. Так что не все так плохо. Я уверен, что вы знаете это, основываясь на деталях вашего вопроса, но я предполагаю, что другие читатели не могут.
Мэтт Уитфилд
-2

Насколько я знаю, невозможно добавить покрывающие столбцы в первичный ключ

Если у вас есть кластеризованный индекс в KeyColumn, то, поскольку он является кластерным индексом, все остальные столбцы неявно «покрыты». Таким образом, вы ничего не получите, добавив еще один индекс на KeyColumn. На самом деле вы замедляете вставки и занимает больше места.

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

Дэвид Руссел
источник
2
Из первого абзаца:The table is clustered by another column entirely.
JNK
5
Я думаю, что здесь может быть некоторая путаница первичного ключа / кластерного индекса. Несмотря на все усилия руководства студии убедить вас, это не одно и то же.
Мэтт Уитфилд