Sqlserver分区笔记

当一个数据表太大,且数据还在进一步增长情况下,查询会越来越慢,这个时候我们就考虑怎么优化,表分区是其中一个方式,将一个文件分成多个文件,使得数据文件的读取速度变快。下面直接进行分区语句创建,根据语句来理解分区如何使用。

1、分区即为分文件,创建文件组,文件组对应一个文件

--1、创建文件组
ALTER  DATABASE  demo_metro ADD  FILEGROUP  Q_5S_fileGroup_202101;
--2、创建分区文件
ALTER DATABASE demo_metro ADD  FILE (NAME =N'Q_5S_file_202101',FILENAME=N'D:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\DATA\Q_5S_file_202101.ndf',size=5Mb,filegrowth=5mb) TO  FILEGROUP  Q_5S_fileGroup_202101

2、创建分区函数

--3、创建分区函数
CREATE PARTITION FUNCTION [Q_5S_PartitionFun](DATETIME) AS RANGE RIGHT FOR VALUES (N'2021-01-01')

分区函数指定分区规则,本例按照月份分文件,将文件按照时间轴2021-01-01分割成2个部分,2021-01-01之前一个文件,2021-01-01之后一个文件

3、创建分区方案

--4、创建分区方案
CREATE PARTITION SCHEME [Q_5S_PartitionSchema] AS PARTITION [Q_5S_PartitionFun] TO ([PRIMARY], Q_5S_fileGroup_202101)

分区方案就是为分区函数添加文件,本例2021-01-01之前写入[PRIMARY],2021-01-01之后的数据写入 Q_5S_fileGroup_202101

根据下图,可以较好的理解分区方案,每个文件组文件对应一个时间段。

4、为表设置分区方案(为分区条件字段设置聚集索引)

资料说明主键Id不可为聚集索引,需要为非聚集索引才行(未验证)

--5、为现有表设置分区方案
CREATE CLUSTERED INDEX IX_CreateDate ON Q_5S(Time)
ON [Q_5S_PartitionSchema] (Time)

5、至此分区已经完成,插入数据,数据自动归属各自分区(按照时间区分)

6、分区完成,但是既然是按照时间区分,那么自然需要按照时间动态创建分区文件,比如每个月生成一个新的文件组和文件,如下图

直接上存储过程,存储过程需要在每月的一号执行一次(使用作业,作业使用方式后续补全)

-- =============================================  
-- Author:      zzheng  
-- Create date: 2021-01-28  
-- Description: 动态分区
-- =============================================  
ALTER PROCEDURE  [dbo].[proc_create_table_partition]  
    (@now DATETIME,@dbname NVARCHAR(20),@tablename NVARCHAR(50),@schemanname NVARCHAR(50),@functionname NVARCHAR(50))  
AS  
BEGIN  
    --文件组名称  
    DECLARE  @fileGroupName VARCHAR(32);  
    --文件名称  
    DECLARE  @fileName VARCHAR(512);  
    -- 保存202001这样的日期  
    DECLARE @yyyymm VARCHAR(8);  
    -- 保存 2021-01-01 这样的日期  
    DECLARE @yyyy_mm_dd VARCHAR(10);
    SET @yyyymm='_'+CONVERT (VARCHAR(6),@now,112);
    SET @yyyy_mm_dd= CONVERT (VARCHAR(7),@now,120)+'-01';
    --定义文件组名称  
    SET @fileGroupName=@tablename+'_fileGroup'+@yyyymm;
    --判断组是否已经创建  
    IF NOT  EXISTS(SELECT  1 FROM  sys.filegroups WHERE  name =@fileGroupName)   
    BEGIN   
        --创建文件组,因为alter database 这些是不支持事务的,所以只能通过条件来控制  
        EXEC('alter database '+@dbname+' add filegroup '+@fileGroupName);
    END
    --print @yyyymm;
    --创建文件,并分追加到组中  
    IF NOT  EXISTS(SELECT 1 FROM sys.database_files WHERE name=@tablename+'_file'+@yyyymm) 
	  BEGIN    
        --查询主文件目录  
		--D:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\DATA\test
        SELECT  @fileName=SUBSTRING(physical_name,1,LEN(physical_name)-LEN(name)-4) FROM  master.sys.master_files WHERE type_desc='ROWS' and name=@dbname   
        --完整的文件名称  
         SET @fileName=@fileName+@tablename+'_file'+@yyyymm+'.ndf';  
          
        --创建文件  
         EXEC('alter database '+@dbname+' add file (name=N'''+@tablename+'_file'+@yyyymm+''',filename=N'''+@fileName+''',size=10Mb,filegrowth=2mb) to filegroup '+@fileGroupName)
        --修改分区方案(方案依赖函数,所以先修改方案)  
         exec('ALTER PARTITION SCHEME ['+@schemanname+']  NEXT USED '+@fileGroupName)
        --修改分区函数,添加分区  
		--ALTER PARTITION FUNCTION [COP_5S_PartitionFun]() SPLIT RANGE(N''+@yyyy_mm_dd);
		 exec('alter partition function '+@functionname+'() split range('''+@yyyy_mm_dd+''')')
         
     END      
END

7、附上查询分区数据

--$partition.COP_5S_PartitionFun(time)=3:分区编码
SELECT * FROM dbo.COP_5S WHERE  $partition.COP_5S_PartitionFun(time)=3
--根据时间点(分区函数分隔时间)来查询该分区的数据
SELECT COUNT(1) FROM COP_5S(NOLOCK) WHERE $partition.COP_5S_PartitionFun(time)=$partition.COP_5S_PartitionFun('2021-02-01')

写在最后的一些经验:

表分区之后删除很麻烦,需要彻底删除文件、文件组、分区函数、分区方案、表分区字段索引。而删除这些的前提是表没有分区或者不是当前绑定的当前分区方案,因此可以新建一个临时分区策略用于绑定(无法直接解绑),绑定完之后数据自动移到新的方案文件下,之后可以删除旧的策略、函数、文件、文件组;

--1、删除旧索引
DROP INDEX IX_Time_Data_Point
--2、绑定新方案,假如已经创建好方案Temp_PartitionSchema
CREATE CLUSTERED INDEX IX_Time_Data_Point ON data_Points(Time)
ON [Temp_PartitionSchema] (Time)

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值