Як розділити існуючу нерозділену таблицю


22

У мене є існуюча таблиця з даними:

dbo.Test (col1,col2,col3....) ON [PRIMARY]

Мені потрібно змінити цю таблицю, щоб поділити її так:

dbo.Test(col1,col2,col3....) ON Ps_Date(Col2)

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

Відповіді:


23

Щоб розділити таблицю, ви можете виконати нижче короткі кроки:

  • спочатку створіть функцію розділу та схему розділів
  • Після цього можна розділити таблицю.
  • Якщо у вашій таблиці є кластерний індекс, то вам потрібно скинути і відтворити його на правому розділі, або ви можете скористатись DROP_EXISTINGпунктом для повторного створення кластерного індексу.
  • Якщо у вашій таблиці немає кластерного індексу, ви можете просто створити її на правому розділі за допомогою схеми розділів.
  • Також Enterprise Edition має гнучкість використання ONLINE=ONопції CREATE INDEX, щоб мінімізувати час простою для вашої програми. Зауважте, що під час перебудови індексу за допомогою параметра ONLINE ви побачите пониження продуктивності.

Щоб автоматизувати розподіл, ви можете використовувати утиліту SQL Server Partition Management або SQL Server Particified Framework Framework, доступну також у codeplex.

Деякі хороші ресурси:


53

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

Я буду використовувати приклад функції розділу, схеми розділів та таблиці:

CREATE PARTITION FUNCTION pf1(INT) AS RANGE LEFT FOR VALUES(10,20,30,40);
GO
CREATE PARTITION SCHEME ps1 AS PARTITION pf1 ALL TO ([PRIMARY])
GO
CREATE TABLE dbo.pt(pc INT NOT NULL, id INT NOT NULL) ON [PRIMARY];
GO

1. У вашій таблиці є кластерний індекс, який не був створений обмеженням.

Це найпростіший випадок. Ви можете просто використовувати CREATE INDEXоператор з DROP_EXISTINGпунктом для переміщення таблиці до схеми розділів.

Припустимо для прикладу, що цей кластерний індекс був створений:

CREATE UNIQUE CLUSTERED INDEX ptc ON dbo.pt(Id) ON [PRIMARY];

Щоб розділити цю таблицю, кластерний індекс включив стовпчик розділів (pt у нашому випадку) як частину ключа. Це твердження змінює кластерний індекс, щоб він включав стовпчик розділу та розділи його одночасно:

CREATE UNIQUE CLUSTERED INDEX ptc ON dbo.pt(pc, Id) WITH(DROP_EXISTING = ON)ON ps1(pc) ;

DROP_ExistingПункт автоматично видаляє існуючий індекс , перш ніж створювати новий. Це бажано над окремим, DROP INDEXоскільки це призводить до того, що некластеризовані індекси відбудуються лише один раз.

2. У вашій таблиці є кластерний індекс, який є частиною PRIMARY KEYабо UNIQUEобмеженням, і він містить стовпчик розділу як частину ключа

Цей ще легкий і дуже схожий на попередній.

Припустимо, це PRIMARY KEYобмеження було створене на столі:

ALTER TABLE dbo.pt ADD CONSTRAINT ptc PRIMARY KEY CLUSTERED (pc, Id) ON [PRIMARY];

Тепер ви можете просто запустити той самий сценарій відновлення, який ми використовували в 1:

CREATE UNIQUE CLUSTERED INDEX ptc ON dbo.pt(pc, Id) WITH(DROP_EXISTING = ON)ON ps1(pc) ;

3. У таблиці є кластерний індекс, який не включає стовпчик розділів, але був створений як частина PRIMARY KEYабо UNIQUEобмеження

Жорстка удача. Ви не можете змінити визначення PRIMARY KEYабо UNIQUEобмеження після факту. Єдиний варіант - скинути обмеження, а потім або відтворити його, включаючи стовпець розділу, або створити кластерний індекс, незалежний від обмеження, що включає стовпчик розділу. У другому випадку ви можете заново створити обмеження, NONCLUSTEREDне включаючи стовпчик розділу. Оскільки тепер це обмеження не вирівняне (тобто його індекс підтримки не розділений), ви повинні вказати, де його розмістити на диску.

Припустимо, у таблиці був такий первинний ключ:

ALTER TABLE dbo.pt ADD CONSTRAINT ptc PRIMARY KEY CLUSTERED (Id) ON [PRIMARY];

Щоб розділити цю таблицю, потрібно спочатку скинути обмеження:

ALTER TABLE dbo.pt DROP CONSTRAINT ptc;

Потім потрібно створити розділений кластерний індекс:

CREATE UNIQUE CLUSTERED INDEX ptci ON dbo.pt(pc, Id) ON ps1(pc) ;

Якщо ви вирішите знову створити PRIMARY KEYобмеження, яке не є вирівняним, ви можете зробити так:

ALTER TABLE dbo.pt ADD CONSTRAINT ptc PRIMARY KEY NONCLUSTERED (Id) ON [PRIMARY];

4. У вашій таблиці немає кластерного індексу

У цьому випадку в більшості випадків рекомендується просто створити кластерний індекс для встановлення розділення. Для цього ви можете використовувати раніше переглянуті оператори створення індексу:

CREATE UNIQUE CLUSTERED INDEX ptci ON dbo.pt(pc, Id) ON ps1(pc) ;

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

Припустимо, у вашій таблиці немає кластерного індексу. Щоб розділити таблицю, потрібно спочатку створити CLUSTERED UNIQUEобмеження. (Ви також можете використовувати CLUSTERED PRIMARY KEYобмеження). Якщо у вас є унікальна комбінація стовпців, це простий крок:

ALTER TABLE dbo.pt ADD CONSTRAINT ptc UNIQUE CLUSTERED(pc,id);

Після створення обмеження ви можете скинути його знову і "перемістити" таблицю до нової схеми розділів одночасно:

ALTER TABLE dbo.pt DROP CONSTRAINT ptc WITH(MOVE TO ps1(pc));

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

ALTER TABLE dbo.pt ADD tmp_id INT IDENTITY(1,1);

Однак це вимагатиме ексклюзивного блокування таблиці, поки всі рядки не будуть оцінені. Залежно від розміру столу це може тривати довгий час. Після створення стовпця виконайте вищевказані два кроки, щоб спершу створити UNIQUEобмеження, а потім знову відкинути його. Після цього ви також можете знову скинути стовпчик. Всі ці кроки досить нав'язливі, тому вам, мабуть, краще просто створити кластерний індекс на столі. Це навіть не повинно бути унікальним.


Якщо у вас є Enterprise Edition, ви можете скористатись WITH(ONLINE=ON)пунктом більшості висловлювань вище. Це дозволить тримати ваш стіл доступним для інших з'єднань. Однак протягом цього часу буде впливати на ефективність роботи.


1
Чудово, Сабастьян! Просто квартира відмінна! Просто для додання №3 вище ... якщо ви хочете використовувати SWITCH увімкнення чи вимкнення, всі індекси повинні бути вирівняні. Створення некластеризованого, нерівневого ПК не дозволить вам здійснити SWITCH, якщо ви не зробите кроки, щоб скинути індекс спочатку, зробіть SWITCH (у якому напрямку він не був) та відновіть індекс. Це дуже часто все-таки швидше, ніж робити еквівалент з делетами, і, звичайно, якщо вам не потрібно використовувати SWITCH, це не буде проблемою.
Джефф Моден
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.