SQL Server 2008 - Індекси розділення та кластеризації


16

Тож дозвольте мені передмовити, сказавши, що я не маю тотального контролю над моїм дизайном db, тому для цілей цього сценарію не можна змінити багато аспектів поточної системи .

Коментарі про те, як ми повинні переосмислити аспекти дизайну, ймовірно, правильні, але непотрібні :)

У мене дуже велика таблиця, приблизно 150 полів завширшки і близько 600 м рядків, яка керує великою кількістю процесів. Це в ситуації зі сховищем даних, тому у нас немає будь-яких оновлень / вставок поза запланованим процесом завантаження, тому він сильно індексується.

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

В даний час ми кластеризуємося на поле, яке ми будемо називати IncidentKey, varchar(50)а не унікальне - у нас може бути від 1 до 100 записів з однаковимиIK (будь-яких коментарів, будь ласка). Ми часто отримуємо нові дані про старі IncidentKeyзаписи, тому вони також не є послідовними.

Я розумію, що мені потрібно включити моє поле розділів IncidentDate, в мій кластерний індексний ключ, щоб розділ працював правильно. Я думаю, що це було бIncidentKey, IncidentDate .

Питання полягає в тому, як буде працювати механізм кластеризованого індексу над 2-частинним ключем у розділеній таблиці, якщо запис у «новому» розділі повинен бути перед записом у «старому» розділі в кластерному індексі?

Наприклад, у мене є 5 записів:

IncidentKey    Date

ABC123        1/1/2010
ABC123        7/1/2010
ABC123        1/1/2011
XYZ999        1/1/2010
XYZ999        7/1/2010

Якщо я отримаю новий запис, ABC123, 2/1/2011він повинен бути в кластерному індексі ДО ПЕРЕД XYZ999, 1/1/2010 . Як це працює?

Я припускаю фрагментацію та покажчики, але я не можу знайти будь-яку інформацію про фізичне зберігання та конфігурацію нерозподілених кластерних індексів на розділених таблицях з клавішами подвійної частини.


Чому було прийнято рішення про поділ таблиці? Які очікувані переваги від розподілу?
Рем Русану

@Remus - я насправді роблю це як тест, тому у нас буде одна розділена і одна нероздільна версія. Очікувана вигода - це зменшення часу завантаження та час складання індексу. Ми робимо щомісячні операції ETL, що займають близько тижня, і сподіваємось, що це значно скоротить цей час. У нас також розміщено близько 3 ТБ, які ми сподіваємося зменшити за рахунок цього.
JNK

Відповіді:


18

Розділена таблиця насправді більше схожа на набір окремих таблиць, зшитих між собою. Отже, у вашому прикладі кластеризації за IncidentKeyрозділами та за допомогою IncidentDate, скажіть, що функція розділення розбиває таблиці на два розділи, так що 1/1/2010 є в розділі 1, а 7/1/2010 - розділом другим. Дані будуть розміщені на диску у вигляді:

Partition 1:
IncidentKey    Date
ABC123        1/1/2010
ABC123        1/1/2011
XYZ999        1/1/2010

Partition 2:
IncidentKey    Date
ABC123        7/1/2010
XYZ999        7/1/2010

На низькому рівні насправді є два різних набори рядків. Це процесор запитів, який видає ілюзію єдиної таблиці, створюючи плани, які шукають, сканують і оновлюють всі набори рядків разом, як один.

Будь-який рядок у будь-якому некластеризованому індексі, скажімо, має кластерний індексний ключ, якому він відповідає ABC123,7/1/2010. Оскільки кластерний індексний ключ завжди містить стовпчик ключа розбиття, двигун завжди буде знати, в якому розділі (наборі рядків) кластерного індексу шукати це значення (у цьому випадку в розділі 2).

Тепер, коли ви маєте справу з розділенням, ви повинні врахувати, чи будуть ваші індекси NC вирівняні (індекс NC розділений точно так само, як кластеризований індекс) або не вирівняний (індекс NC нерозподілений, або розділений інакше, ніж кластерний індекс) . Неспрямовані індекси є більш гнучкими, але вони мають деякі недоліки:

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

  • вирівняні індекси означають, що унікальні обмеження більше не можна створювати / застосовувати (за винятком стовпця розділення)
  • всі зовнішні ключі, на які посилається розділена таблиця, повинні містити ключ розподілу у співвідношенні (оскільки ключ розділення є через вирівнювання у кожному індексі), і це, в свою чергу, вимагає, щоб усі таблиці, на які посилається розділена таблиця, містили значення стовпця ключа розділу. Подумайте Orders-> OrderDetails, якщо Orders має OrderID, але він розділений на OrderDate, тоді OrderDetails повинен містити не тільки OrderID, але й OrderDate, щоб правильно оголосити обмеження зовнішнього ключа.

Ці ефекти я рідко виявляв на початку проекту, який розгортає розділення, але вони існують і мають серйозні наслідки.

Якщо ви вважаєте, що вирівняні індекси є рідкісним або крайнім випадком, то врахуйте це: у багатьох випадках наріжним каменем ETL та розбиття рішень є швидке включення таблиць постановки. Для переключення в операції потрібні вирівняні індекси.

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


Ідеально, це саме те, що я шукав. Нам потрібно буде використовувати вирівняні індекси b / c, заміни є частиною жеребкування для того, що ми хочемо зробити з цим. Ми також робимо TON сукупних функцій, що групуються на цьому IncidentKeyполі, і я думаю, що це серйозно завадить. Я ціную всі деталі!
JNK

Зазвичай переваги операцій комутації розділів переважають усі проблеми.
Рем Русану

Ось наша надія, ми побачимося незабаром!
JNK

9

Коли кластерний індекс має кілька розділів, кожен розділ має структуру B-дерева, яка містить дані для цього конкретного розділу. Наприклад, якщо кластерний індекс має чотири розділи, є чотири структури B-дерева; по одному в кожній секції. Реф. Структуровані структури індексів

Спеціальні вказівки щодо розділених індексів

Можна відновити конкретні розділи розділеного індексу.

напр

ALTER INDEX IX_TransactionHistory_TransactionDate
ON Production.TransactionHistory
REBUILD Partition = 5;
GO

+1 Для посилання я прочитав спеціальні вказівки, але пропустив цей параграф. Подальше запитання - ми робимо безліч агрегацій на IncidentKeyмісцях, чи вважаєте ви, що це негативно вплине на продуктивність (я розумію, мені все одно доведеться робити тестування)?
JNK

Я не знаю всіх ваших конкретних обставин, але мені здається, що вам може бути краще розділити розділ на IncidentDate?
Мітч Пшеничний

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