Чи має значення порядок стовпців в індексі ПК?
Так.
За замовчуванням обмеження первинного ключа застосовується в SQL Server унікальним кластерним індексом. Кластерний індекс визначає логічний порядок рядків у таблиці. Може бути додано кілька додаткових сторінок індексу для представлення верхніх рівнів індексу b-дерева, але найнижчий (листовий) рівень кластерного індексу - це просто логічний порядок самих даних.
Щоб зрозуміти це, рядки на сторінці не обов'язково фізично зберігаються в кластерному порядку індексних ключів. Всередині сторінки є окрема структура непрямості, яка зберігає вказівник на кожен рядок. Ця структура сортується за кластеризованими індексними ключами. Також кожна сторінка має вказівник на попередню та наступну сторінку на одному рівні в кластерному порядку індексних ключів.
За допомогою кластеризованого первинного ключа (RowNumber, DataDate)
рядки логічно впорядковуються спочатку, RowNumber
а потім по DataDate
- тому всі рядки, де RowNumber = 1
логічно згруповані, потім рядки, де RowNumber = 2
і так далі.
Коли ви додаєте нові дані (з RowNumbers
1 по n), нові рядки логічно належать до існуючих сторінок, тому SQL Server, ймовірно, повинен зробити багато роботи з розділенням сторінок, щоб звільнити місце. Вся ця діяльність породжує багато зайвої роботи (включаючи реєстрацію змін) без вигоди.
Розбиті сторінки також починаються приблизно на 50% порожніми, тому надмірне розбиття може призвести до низької щільності сторінки (менше рядків, ніж оптимальна для кожної сторінки). Ця погана новина не тільки для читання з диска (менша щільність = більше сторінок для читання), але й сторінки нижчої щільності займають більше місця в пам'яті при кешуванні.
Зміна кластерного індексу на (DataDate, RowNumber
) означає, що нові дані (з, мабуть, вищими, DataDates
ніж зараз зберігаються) додаються до логічного кінця кластерного індексу на нових сторінках. Це призведе до видалення зайвих накладних витрат на розбиття сторінок і призведе до більш швидкого завантаження. Менш фрагментовані дані також означають, що активність читання наперед (читання сторінок з диска, перш ніж вони знадобляться для запиту, що триває) може бути ефективнішою.
Якщо нічого іншого, ваші запити будуть набагато частіше шукати, DataDate
ніж RowNumber
. Кластеризований індекс на (DataDate, RowNumber
) підтримує пошук індексу DataDate
(і потім RowNumber
). Існуюча композиція підтримує лише пошук RowNumber
(і лише тоді, можливо, на DataDate
). Можливо, ви зможете скинути існуючий некластеризований індекс DataDate
після того, як буде змінено первинний ключ. Кластерний індекс буде ширшим за некластеризований індекс, який він замінює, тому слід перевірити, щоб продуктивність залишалася прийнятною.
Імпортуючи нові дані за допомогою bcp
, ви можете отримати більш високу ефективність, якщо дані у файлі імпорту відсортовані за кластеризованими індексними клавішами (в ідеалі (DataDate, RowNumber
) і ви вкажете bcp
параметр:
-h "ORDER(DataDate,RowNumber), TABLOCK"
Для найкращої продуктивності завантаження даних, ви можете спробувати домогтися мінімально зафіксованих даних. Для отримання додаткової інформації див: