Вы не указываете, имеет ли ваша таблица кластеризованный индекс или нет, поэтому давайте рассмотрим все варианты.
Я собираюсь использовать этот пример функции секционирования, схемы секционирования и таблицы:
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)
предложение для большинства приведенных выше утверждений. Это сделает вашу таблицу доступной для других соединений. Тем не менее, в течение этого времени будет влияние на производительность.