MS Sql Server 2005 分区表有点麻烦

时间:2023-02-13 11:09:20

ALTER DATABASE AdventureWorks ADD FILEGROUP [2003Q3]


创建文件组后,使用 ALTER DATABASE 将文件添加到该文件组中。

ALTER DATABASE AdventureWorks
ADD FILE
(NAME = N'2003Q3',
FILENAME = N'C:/AdventureWorks/2003Q3.ndf',
SIZE = 5MB,
MAXSIZE = 100MB,
FILEGROWTH = 5MB)
TO FILEGROUP [2003Q3]

 

确定是否应使用多个文件组
  为了有助于优化性能和维护,应使用文件组分离数据。文件组的数目一定程度上由硬件资源决定:一般情况下,文件组数最好与分区数相同,并且这些文件组通常位于不同的磁盘上。但是,这主要适用于打算对整个数据集进行分析的系统。如果您有多个 CPUSQL Server 则可以并行处理多个分区,从而大大缩短处理大量复杂报表和分析的总体时间。这种情况下,可以获得并行处理以及在分区表中移入和移出分区的好处。

 

 

边上的同事说文件组包含多个文件可以增加并行度,也就是多个CPU可以一起读?
他的意思难道是说操作系统对程序访问单个文件有限制,多了话会阻塞?
如果是的话 Windows 2003 64位 企业版  文件有大小限制 有并行访问的限制不?
他还说可以把它们分配到不同磁盘上。不过如今都用Raid 10了 不需要人为的分成多个文件,反而增加维护复杂度。
他接着说 文件小而多比大而少 容易备份!
他说的是真的吗?

因此本人还是采用一个文件组和一个文件.其实就是用原来的数据文件的.

建立分区函数

CREATE PARTITION FUNCTION FuPart_szumevent(datetime)AS RANGE RIGHT FOR VALUES ('20070801','20070901','20071001','20071101','20071201','20080101','20080201','20080301','20080401','20080501','20080601','20080701','20080801','20080901','20081001','20081101','20081201')
 这里采用的是范围分区。 这里有个Right 和Left 。Right比较容易理解 它是小于时间点的是另外个分区数据,大于和等于它的是所在的分区。

A<Time1<=B<Time2<=C  而Left是反过来 A>=Time1>B>=Time2>C

Left 有个麻烦点是 >=Time1 => 2008-01-01 23:59:59.997

 

建立分区架构:

CREATE PARTITION SCHEME FNw_szumevent AS PARTITION FuPart_szumevent ALL TO ([PRIMARY])

其实就是关联东东,或许Ms认为以后DBA会对分区表进行改用分区函数

建立分区表:
CREATE TABLE [dbo].[Part_SzumEvent](
 [id] [uniqueidentifier] NOT NULL,
 [fid] [bigint] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
 [show_color] [nvarchar](64) COLLATE Chinese_PRC_CI_AS NULL,
 CONSTRAINT [PK_Part_SzumEvent] PRIMARY KEY NONCLUSTERED
( [id] ASC )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]  --关键字使用文件组
) ON [FNw_szumevent]([start_case_time])--挂接分区架构和分区列

 

从旧表插入3万多数据

insert into Part_SzumEvent select * from szum_event --32855

报错:消息 8101,级别 16,状态 1,第 1 行 An explicit value for the identity column in table 'Part_SzumEventA'
can only be specified when a column list is used and IDENTITY_INSERT is ON.

 

然后去修改这列,取消该自动增量 “Part_SzumEventA”表 - 无法修改表。  Incorrect syntax near the keyword 'DEFAULT'  没办法只好删除它  插入后重建

 

建立聚集分区索引
CREATE CLUSTERED INDEX [Idx_SE_StaTime] ON [dbo].[Part_SzumEvent]
( [start_case_time] ASC )WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [FNw_szumevent]([start_case_time])


查看分区情况
select
partition = $partition.FuPart_szumevent(start_case_time) ,
rows  = count(*) ,
minval    = min(start_case_time),     
maxval    = max(start_case_time)
 from dbo.Part_SzumEvent
group by $partition.FuPart_szumevent(start_case_time)
order by partition

 

 

查看实际性能
select * from szum_event where start_case_time <= convert(smalldatetime,'2007-09-01')
计划为访问关键字的聚集索引 IO 2.18  CPU 0.036 实际行数为42  估计行数142
最后的Select  子树大小 2.2164 并行度 1 估计行数 142.9

 

select * from Part_szumevent where start_case_time <= convert(smalldatetime,'2007-09-01')
计划为访问Idx_SE_StaTime的聚集索引 计划比较多步 要经过计算标量,常量扫描,嵌套循环
io 0.00046 cpu 0.0003078 实际行数为42  估计行数41.9
最后的Select  子树大小 0.015272 并行度 1 估计行数 125.8


另外可以参考下: 本人成功地在旧表通过删除再建立聚集索引来解决了 哈哈
 将无分区表转换为已分区表
可以通过以下两种方式之一将现有的无分区表转变为已分区表。

一种方式是通过使用 CREATE INDEX 语句对表创建已分区聚集索引。此操作类似于对任一表创建聚集索引,因为 SQL Server 实质上将删除表并以聚集索引格式重新创建该表。如果已经对表应用了某个已分区聚集索引,则可以使用带有 DROP EXISTING = ON 子句的 CREATE INDEX 删除该索引并以某种分区方案重新生成该索引。

有关聚集索引的信息,请参阅聚集索引设计指南。

另一种方式是使用 Transact-SQL ALTER TABLE SWITCH 语句将表中的数据切换到只有一个分区的按范围分区的表中。此已分区表在转换发生之前必须已经存在,并且该表的单个分区必须为空。有关切换分区的详细信息,请参阅使用分区切换高效传输数据。将表修改为已分区表之后,可以修改其分区函数以增加分区,如前面修改分区函数中所述。

将现有表转换为已分区表

CREATE INDEX (Transact-SQL)

ALTER TABLE (Transact-SQL)

 将已分区表转换为无分区表
将已分区表更改为无分区表仅涉及到修改已分区表的分区函数,以使该表仅由一个分区组成。尽管这从技术上说仍然是已分区表,但此状态与要对该表执行的任何后续操作不相干。

如果已经对表应用了已分区聚集索引,则可以通过删除该索引并将其作为无分区索引重新生成来获得相同的结果。可使用带有 DROP EXISTING = ON 子句的 Transact-SQL CREATE INDEX 命令来执行此操作。