SQL Server 2005 中的分区表和索引应用
SQL Server 2005引入的表分区 技术,让用户能够把数据分散存放到不同的物理磁盘中,提高这些磁盘的并行处理性能以优化查询性能。
表分区步骤:
1. 创建文件组
下面建了三个分区,分别表示2008-2009年的订单数据,分属不同的磁盘上面:
2. 为范围分区创建分区函数
不过这种情况我们可以再程序中处理避免。
现在可以插入数据了
可以改变时间@date的值,然后会发现原来数据库中的文件并没有变化,而刚才新建在其他磁盘下的文件会根据你插入的数据的变化。
分区表的操作采用了CPU和I/O的并行操作,检索数据的数据量也变小了,定位数据所耗时间变短。
查看分区表数据:
如何修改分区表:
比如现在是2010年了,接下来又要新增一个新的分区来保存2011年的数据了,或者保存将来几年的数据;
1. 新建将来几年的文件组(方法和上面新建文件组的方法一下)
2. 首先修改分区架构
3. 修改分区函数
在已经存在的表上新建表分区:
目前我的办法是新建一个表分区,然后把数据导入过去,不知道这个办法好不好,研究中......
表分区步骤:
1. 创建文件组
下面建了三个分区,分别表示2008-2009年的订单数据,分属不同的磁盘上面:
ALTER DATABASE FrameWork ADD FILEGROUP [2009_Order]
ALTER DATABASE FrameWork
ADD FILE
(NAME = N'2009_Order',
FILENAME = N'E:\FrameWork\2009_Order.ndf',
SIZE = 20G,
MAXSIZE = 100G,
FILEGROWTH = 5G)
TO FILEGROUP [2009_Order]
ALTER DATABASE FrameWork ADD FILEGROUP [2008_Order]
ALTER DATABASE FrameWork
ADD FILE
(NAME = N'2008_Order',
FILENAME = N'F:\FrameWork\2008_Order.ndf',
SIZE = 20G,
MAXSIZE = 100G,
FILEGROWTH = 5G)
TO FILEGROUP [2008_Order]
ALTER DATABASE FrameWork ADD FILEGROUP [2010_Order]
ALTER DATABASE FrameWork
ADD FILE
(NAME = N'2010_Order',
FILENAME = N'G:\FrameWork\2010_Order.ndf',
SIZE = 20G,
MAXSIZE = 100G,
FILEGROWTH = 5G)
TO FILEGROUP [2010_Order]
FrameWork 是数据库名称 [2009_Order]表示文件名称 FILENAME 表示文件路径 ALTER DATABASE FrameWork
ADD FILE
(NAME = N'2009_Order',
FILENAME = N'E:\FrameWork\2009_Order.ndf',
SIZE = 20G,
MAXSIZE = 100G,
FILEGROWTH = 5G)
TO FILEGROUP [2009_Order]
ALTER DATABASE FrameWork ADD FILEGROUP [2008_Order]
ALTER DATABASE FrameWork
ADD FILE
(NAME = N'2008_Order',
FILENAME = N'F:\FrameWork\2008_Order.ndf',
SIZE = 20G,
MAXSIZE = 100G,
FILEGROWTH = 5G)
TO FILEGROUP [2008_Order]
ALTER DATABASE FrameWork ADD FILEGROUP [2010_Order]
ALTER DATABASE FrameWork
ADD FILE
(NAME = N'2010_Order',
FILENAME = N'G:\FrameWork\2010_Order.ndf',
SIZE = 20G,
MAXSIZE = 100G,
FILEGROWTH = 5G)
TO FILEGROUP [2010_Order]
2. 为范围分区创建分区函数
CREATE PARTITION FUNCTION OrderDateRangePFN(datetime)
AS
RANGE LEFT FOR VALUES ('20081231 23:59:59.997',
'20091231 23:59:59.997')
使用 datetime 数据类型确实增加了一定的复杂性,复杂性增加是因为 datetime 数据类型具有精度。必须选择 23:59:59.997 的原因在于,datetime 数据无法保证毫秒级别的精度。相反,datetime 数据的精度在 3.33 毫秒内。使用 23:59:59.999 这个确切的时间值是不行的,因为该值将被舍入到最接近的时间值,即第二天的 12:00:00.000 A.M。由于进行了这种舍入,将无法正确定义边界。对于 datetime 数据,必须对明确提供的毫秒值加倍小心。 AS
RANGE LEFT FOR VALUES ('20081231 23:59:59.997',
'20091231 23:59:59.997')
不过这种情况我们可以再程序中处理避免。
第一个分区将包含所有小于或等于 '20081231 23:59:59.997' 的值
第二个分区将包含所有小于或等于 '20091231 23:59:59.997' 而且 大于 ‘20081231 23:59:59.997’
第三个分区将包含所有大于或者等于 '20091231 23:59:59.997' 的值
3. 创建分区架构CREATE PARTITION SCHEME OrderDatePScheme
AS
PARTITION OrderDateRangePFN
TO ([2008_Order], [2009_Order],[2010_Order])
4. 创建分区表 AS
PARTITION OrderDateRangePFN
TO ([2008_Order], [2009_Order],[2010_Order])
--创建分区表
CREATE TABLE [dbo].[OrdersRange]
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[OrderName] [nvarchar](100) NULL,
[OrderNumber] [int] NULL,
[OrderTime] [datetime] NULL,
[OrderText] [ntext] NULL
)
ON OrderDatePScheme ([OrderTime])
GO
CREATE TABLE [dbo].[OrdersRange]
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[OrderName] [nvarchar](100) NULL,
[OrderNumber] [int] NULL,
[OrderTime] [datetime] NULL,
[OrderText] [ntext] NULL
)
ON OrderDatePScheme ([OrderTime])
GO
现在可以插入数据了
DECLARE @Counter INT
declare @date datetime
SET @Counter = 0
SET @date = '2010-10-1'
WHILE (@Counter < 50000000)
BEGIN
insert into [OrdersRange] ([OrderName],[OrderNumber],[OrderTime],[OrderText])
values('2009 年数据',100,@date,'测试数据测试数据测试数据测试数据')
SET @Counter = @Counter + 1
END
declare @date datetime
SET @Counter = 0
SET @date = '2010-10-1'
WHILE (@Counter < 50000000)
BEGIN
insert into [OrdersRange] ([OrderName],[OrderNumber],[OrderTime],[OrderText])
values('2009 年数据',100,@date,'测试数据测试数据测试数据测试数据')
SET @Counter = @Counter + 1
END
可以改变时间@date的值,然后会发现原来数据库中的文件并没有变化,而刚才新建在其他磁盘下的文件会根据你插入的数据的变化。
分区表的操作采用了CPU和I/O的并行操作,检索数据的数据量也变小了,定位数据所耗时间变短。
查看分区表数据:
SELECT $PARTITION.OrderDateRangePFN(OrderTime) AS OrderTime, count(*) AS [Rows In Partition]
FROM [OrdersRange] GROUP BY $partition.OrderDateRangePFN(OrderTime)
FROM [OrdersRange] GROUP BY $partition.OrderDateRangePFN(OrderTime)
如何修改分区表:
比如现在是2010年了,接下来又要新增一个新的分区来保存2011年的数据了,或者保存将来几年的数据;
1. 新建将来几年的文件组(方法和上面新建文件组的方法一下)
2. 首先修改分区架构
PARTITION SCHEME OrderDatePScheme
NEXT USED [2011_Order]
上面修改分区架构表示新增了一个分区NEXT USED [2011_Order]
3. 修改分区函数
ALTER PARTITION FUNCTION OrderDateRangePFN()
SPLIT RANGE ('20101231 23:59:59.997')
完成,注意修改完成后要检查书序是否正确,在存储-》分区方案 和 分区函数关系要对应SPLIT RANGE ('20101231 23:59:59.997')
在已经存在的表上新建表分区:
目前我的办法是新建一个表分区,然后把数据导入过去,不知道这个办法好不好,研究中......