SQL Server 2005 中的分区表和索引应用

时间:2022-03-04 00:39:03
      SQL Server 2005引入的表分区 技术,让用户能够把数据分散存放到不同的物理磁盘中,提高这些磁盘的并行处理性能以优化查询性能。
     
       表分区步骤:
       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 表示文件路径       
   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 数据,必须对明确提供的毫秒值加倍小心。 
     不过这种情况我们可以再程序中处理避免。

      第一个分区将包含所有小于或等于 '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. 创建分区表
-- 创建分区表
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

可以改变时间@date的值,然后会发现原来数据库中的文件并没有变化,而刚才新建在其他磁盘下的文件会根据你插入的数据的变化。
分区表的操作采用了CPU和I/O的并行操作,检索数据的数据量也变小了,定位数据所耗时间变短。

 查看分区表数据:
SELECT  $PARTITION.OrderDateRangePFN(OrderTime)  AS  OrderTime,  count ( * AS   [ Rows In Partition ]
       
FROM   [ OrdersRange ]   GROUP   BY  $partition.OrderDateRangePFN(OrderTime)

如何修改分区表:
比如现在是2010年了,接下来又要新增一个新的分区来保存2011年的数据了,或者保存将来几年的数据;
     1. 新建将来几年的文件组(方法和上面新建文件组的方法一下)
     2. 首先修改分区架构
 PARTITION SCHEME OrderDatePScheme
NEXT  USED  [ 2011_Order ]
       上面修改分区架构表示新增了一个分区
     3. 修改分区函数
ALTER  PARTITION  FUNCTION  OrderDateRangePFN() 
SPLIT RANGE (
' 20101231 23:59:59.997 ' )
       完成,注意修改完成后要检查书序是否正确,在存储-》分区方案  和 分区函数关系要对应

在已经存在的表上新建表分区
目前我的办法是新建一个表分区,然后把数据导入过去,不知道这个办法好不好,研究中......