Наслідки використання унікального некластеризованого індексу з покриваючими стовпцями замість первинного ключа


12

У нас є велика таблиця, в [MyTable]якій зараз є і a Primary Key, і a Unique Non Clustered Indexв тому ж стовпці ( [KeyColumn]). Індекс U NC також має додаткові покривні колони.

Наявність як ПК, так і унікального індексу NC в одних стовпцях видається зайвим, тому я розглядав питання про видалення первинного ключа і замість цього використовував унікальний індекс, не кластеризований для цілей референтної цілісності.

Зауважте, що таблиця повністю кластеризована іншим стовпцем.

тобто у нас є:

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 і задоволений аспектами доброчесності та продуктивності.

Моє запитання: Чи є такий підхід хибним?

Редагувати те, що я намагаюся досягти : Оптимізація продуктивності та весняне прибирання . Видаляючи або ПК або індекс, буде менше сторінок, необхідних для моїх індексів = швидше записує, плюс також корисні для обслуговування / експлуатації переваги, тобто один менший індекс для збереження дефрагментів тощо.

Якщо говорити про це, я ніколи раніше не мав таблиці, на яку посилався, без ПК. Однак той факт, що до таблиці було додано індекс NC із стовпцями, що охоплює, означає, що мені потрібно адаптувати своє мислення.


Чи можете ви прокоментувати те, що ви намагаєтеся досягти? Ви також повинні переконатися, що ви в кінцевому підсумку з кластерним індексом.

@ jn29098 - оновлено. Підтверджено, що у нас є кластерний індекс, на стовпчиках, які не є ні PK, ні стовпчиками покриття, тому це не здається актуальним для цього рішення.
StuartLC

1
Ви впевнені, що у вас немає інструменту моделювання / генерації даних ORM / даних, який би заграв, коли побачить, що ПК втрачено?
Рем Русану

Єдиним недоліком, який я бачу, є те, що після того, як PK зникне. Тоді у вас є лише один індекс на клавіатурній колонці, а запити, які використовують індекс PK, скажіть для сканування індексу на стовпчику клавіш або замовлення клавішними стовпчиками і не охоплені індексом Uniuqe, можуть викликати дещо додаткове введення вводу так як унікальних сторінок аркушів покажчиків набагато більше, ніж у ПК. Інакше це виглядає чудово. Але деякий пурист скаже, що вам слід мати ПК :)
Gulli Meel

1
Я б запропонував вам перевірити корисність цього індексу, використовуючи статистику використання індексу DMV, і побачити, чи використовується він в деяких ваших запитах. Перевірте його і на унікальному ключовому індексі, а потім вирішите, що буде з запитом, використовуючи цей індекс ..
Gulli Meel

Відповіді:


3

Оптимізація продуктивності. Видаляючи або ПК або індекс, буде менше сторінок, необхідних для моїх індексів = швидше записує, плюс також корисні для обслуговування / експлуатації переваги, тобто один менший індекс для збереження дефрагментів тощо

Вам потрібно вміти доводити, що запропоноване насправді допоможе (вартість проти вигоди). З якої причини розглядається ця зміна? Чи є насправді проблеми з ефективністю цієї таблиці, чи вона просто "виглядає неправильно"?

Ось деякі інші питання, які допоможуть вам прийняти найкраще рішення для вашого оточення:

  • Скільки часу буде збережено у вікні обслуговування? У резервному вікні?

  • Скільки місця на цьому збережеться (файли даних, файли журналів, резервні копії тощо)?

  • Чи справдіINSERT продуктивність на цьому столі справді вузьке місце? Наскільки це покращиться? Чи є видалення індексу найкращою стратегією для усунення цієї проблеми?

  • Чи спричинить це проблеми з інструментами та структурами баз даних (особливо для ORM), які очікують, що кожна таблиця матиме первинний ключ, а не лише унікальний індекс? Транзакційна реплікація вимагає первинного ключа в опублікованих таблицях.

  • Чи важлива схема бази даних самодокументування?

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

Особисто кажучи, з того, що ви нам сказали, я б залишив це в спокої, поки не буде доведено, що і (a) додатковий індекс є проблемою, і (b) усунення його - це рішення.


Дякую - виявляється, що показник статистики показав, що ПК все ще активно використовується для сканування. Здається, я перестарався - переваги читабельності / домовленості від збереження ПК повинні з часом переважати будь-які наслідки зберігання. Справа про транзакційну реплікацію - це все ж таки - нам НЕОБХІДНО буде копіювати цю базу даних незабаром.
StuartLC

2

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

Варто мати на увазі, що вартість перевірки референтності цілісності для таблиць, на які посилається ця таблиця, буде вище (знову лише трохи вище).

Поки ви дбаєте про мінливий аспект, тоді вам слід добре вписувати один індекс.

Якби це була моя БД, я, мабуть, пішов би за єдиним унікальним індексом, усі інші речі були б рівними.


Спасибі - чи є у вас посилання на посилання? wrt трохи гірше, ви маєте на увазі виключно нижчу щільність індексу покривного індексу, чи є щось інше, що може спричинити це?
StuartLC

Це, на жаль, з великого досвіду, і спілкування з людьми набагато розумніші за мене за ці роки! І так, саме так - буде менше рядків на сторінці, тим більше вводу-виводу. Однак - варто зазначити, що колонки INCLUDE присутні лише на рівні аркушів. Тож не все погано. Я впевнений, що ви знаєте, що виходячи з деталей вашого запитання, але я здогадуюсь, що інші читачі можуть цього не робити.
Метт Вітфілд,

-2

Наскільки я знаю, не можна додати стовпці покриття до первинного ключа

Якщо у вас є кластерний індекс на KeyColumn, то, оскільки це кластерний індекс, усі інші стовпці неявно 'охоплені'. Таким чином, ви нічого не отримуєте, додаючи ще один індекс на KeyColumn. Насправді ви сповільнить свої вставки та використаєте більше місця.

Це тому, що кластерний індекс - це не індекс як такий, а лише інструкція зберігати рядки таблиці в порядку індексу. А після того, як ви закрепили рядок за допомогою основного ключа, ви маєте всі інші стовпці прямо там.


2
З першого абзацу:The table is clustered by another column entirely.
JNK

5
Я думаю, що тут може відбуватися якась плутанина первинного ключа / кластерного індексу. Незважаючи на всі зусилля менеджменту студії, щоб переконати вас у цьому, це не одне і те ж.
Метт Вітфілд,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.