343*_*343 25 sql-server sql-server-2008-r2 partitioning
我有一个包含数据的现有表:
dbo.Test (col1,col2,col3....) ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)
我需要将此表更改为这样分区:
dbo.Test(col1,col2,col3....) ON Ps_Date(Col2)
Run Code Online (Sandbox Code Playgroud)
我怎样才能在不删除和重新创建表格的情况下实现这一目标?
Seb*_*ine 56
您没有指定您的表是否有聚集索引,所以让我们来看看所有选项。
我将使用这个示例分区函数、分区方案和表:
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
Run Code Online (Sandbox Code Playgroud)
1. 你的表有一个不是由约束创建的聚集索引。
这是最简单的情况。您可以只使用CREATE INDEX带有DROP_EXISTING子句的语句将表移动到分区方案。
假设已经创建了这个聚集索引的例子:
CREATE UNIQUE CLUSTERED INDEX ptc ON dbo.pt(Id) ON [PRIMARY];
Run Code Online (Sandbox Code Playgroud)
为了对这个表进行分区,聚集索引将分区列(在我们的例子中是 pt)作为键的一部分。此语句更改聚集索引以包含分区列并同时对其进行分区:
CREATE UNIQUE CLUSTERED INDEX ptc ON dbo.pt(pc, Id) WITH(DROP_EXISTING = ON)ON ps1(pc) ;
Run Code Online (Sandbox Code Playgroud)
DROP_Existing在创建新索引之前,该子句会自动删除现有索引。这比单独的DROP INDEX更受欢迎,因为它会导致非聚集索引只重建一次。
2. 你的表有一个聚集索引,它是PRIMARY KEYorUNIQUE约束的一部分,它包含分区列作为键的一部分
这一个仍然很容易,并且与前一个非常相似。
假设PRIMARY KEY已经在表上创建了这个约束:
ALTER TABLE dbo.pt ADD CONSTRAINT ptc PRIMARY KEY CLUSTERED (pc, Id) ON [PRIMARY];
Run Code Online (Sandbox Code Playgroud)
现在您可以运行我们在 1 中使用的相同的重新创建脚本:
CREATE UNIQUE CLUSTERED INDEX ptc ON dbo.pt(pc, Id) WITH(DROP_EXISTING = ON)ON ps1(pc) ;
Run Code Online (Sandbox Code Playgroud)
3. 表有一个不包含分区列但作为PRIMARY KEYorUNIQUE约束的一部分创建的聚集索引
倒霉。事后不能更改 aPRIMARY KEY或UNIQUE约束的定义。您唯一的选择是删除约束,然后重新创建包含分区列的约束,或者创建独立于包含分区列的约束的聚集索引。在第二种情况下,您可以重新创建约束NONCLUSTERED而不包括分区列。因为现在这个约束没有对齐(意味着它的支持索引没有分区)你必须指定把它放在磁盘上的位置。
假设表有一个这样的主键:
ALTER TABLE dbo.pt ADD CONSTRAINT ptc PRIMARY KEY CLUSTERED (Id) ON [PRIMARY];
Run Code Online (Sandbox Code Playgroud)
要对该表进行分区,您必须先删除约束:
ALTER TABLE dbo.pt DROP CONSTRAINT ptc;
Run Code Online (Sandbox Code Playgroud)
然后需要创建分区聚集索引:
CREATE UNIQUE CLUSTERED INDEX ptci ON dbo.pt(pc, Id) ON ps1(pc) ;
Run Code Online (Sandbox Code Playgroud)
如果您选择重新创建PRIMARY KEY非对齐约束,您可以这样做:
ALTER TABLE dbo.pt ADD CONSTRAINT ptc PRIMARY KEY NONCLUSTERED (Id) ON [PRIMARY];
Run Code Online (Sandbox Code Playgroud)
4. 你的表没有聚集索引
在这种情况下,建议在大多数情况下只创建一个聚集索引来建立分区。您可以使用之前看到的 create index 语句:
CREATE UNIQUE CLUSTERED INDEX ptci ON dbo.pt(pc, Id) ON ps1(pc) ;
Run Code Online (Sandbox Code Playgroud)
但是,如果您有充分的理由不创建聚集索引,则可以使用以下两步方法。遗憾的是,没有直接的方法可以进行这种更改。
假设您的表没有聚集索引。要对表进行分区,您首先需要创建一个CLUSTERED UNIQUE约束。(您也可以使用CLUSTERED PRIMARY KEY约束)。如果您有一个唯一的列组合,这是一个简单的步骤:
ALTER TABLE dbo.pt ADD CONSTRAINT ptc UNIQUE CLUSTERED(pc,id);
Run Code Online (Sandbox Code Playgroud)
创建约束后,您可以再次删除它并同时将表“移动”到新的分区方案:
ALTER TABLE dbo.pt DROP CONSTRAINT ptc WITH(MOVE TO ps1(pc));
Run Code Online (Sandbox Code Playgroud)
如果您没有唯一的列组合,那么您就不走运了。在这种情况下,您唯一的选择是添加一个新列并用唯一值填充它。如果表相当小,您可以执行以下操作:
ALTER TABLE dbo.pt ADD tmp_id INT IDENTITY(1,1);
Run Code Online (Sandbox Code Playgroud)
但是,这将需要排它表锁,直到所有行都被赋值。根据桌子的大小,这可能会持续很长时间。创建该列后,请按照上述两个步骤首先创建UNIQUE约束,然后立即再次删除它。之后,您还可以再次删除该列。所有这些步骤都相当麻烦,因此您最好只在表上创建一个聚集索引。这甚至不必是唯一的。
如果您有企业版,则可以WITH(ONLINE=ON)在上述大多数语句中使用该子句。这将使您的表可用于其他连接。但是,在此期间会对性能产生影响。
Kin*_*hah 25
要对表进行分区,您可以按照以下简要步骤操作:
DROP_EXISTING子句重新创建聚集索引。ONLINE=ONCREATE INDEX 语句选项来最大限度地减少应用程序的停机时间。请注意,在使用 ONLINE 选项重建索引时,您会看到性能下降。要自动进行分区,您也可以使用Codeplex 上提供的SQL Server 分区管理实用程序或SQL Server 分区表框架。
一些好的资源:
| 归档时间: |
|
| 查看次数: |
68853 次 |
| 最近记录: |