SQL Server 自动循环归档分区数据脚本
原文:SQL Server 自动循环归档分区数据脚本

标签:SQL SERVER/MSSQL SERVER/数据库/DBA/表分区

概述

在很多业务场景下我们需要对一些记录量比较大的表进行分区,同时为了保证性能需要将一些旧的数据进行归档。在分区表很多的情况下如果每一次归档都需要人工干预的话工程量是比较大的而且也容易发生纰漏。接下来分享一个自己编写的自动归档分区数据的脚本,原理是分区表和归档表使用相同的分区方案,循环利用当前的文件组。

一、创建测试数据

----01创建文件组
USE [master]
GO
ALTER DATABASE [chenmh] ADD FILEGROUP [Group1]
GO
ALTER DATABASE [chenmh] ADD FILEGROUP [Group2]
GO
ALTER DATABASE [chenmh] ADD FILEGROUP [Group3]
GO
ALTER DATABASE [chenmh] ADD FILEGROUP [Group4]
GO
USE [master]
GO
ALTER DATABASE [chenmh] ADD FILE ( NAME = N'datafile1', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\datafile1.ndf' , SIZE = 8192KB , FILEGROWTH = 65536KB ) TO FILEGROUP [Group1]
GO
ALTER DATABASE [chenmh] ADD FILE ( NAME = N'datafile2', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\datafile2.ndf' , SIZE = 8192KB , FILEGROWTH = 65536KB ) TO FILEGROUP [Group2]
GO
ALTER DATABASE [chenmh] ADD FILE ( NAME = N'datafile3', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\datafile3.ndf' , SIZE = 8192KB , FILEGROWTH = 65536KB ) TO FILEGROUP [Group3]
GO
ALTER DATABASE [chenmh] ADD FILE ( NAME = N'datafile4', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\datafile4.ndf' , SIZE = 8192KB , FILEGROWTH = 65536KB ) TO FILEGROUP [Group4]
GO----02创建分区函数
USE [chenmh]
GO
CREATE PARTITION FUNCTION [Pt_Range](BIGINT) AS RANGE RIGHT FOR VALUES (1000000, 2000000, 3000000)
GO----03创建分区方案,分区方案对应的文件组数是分区函数指定的数量+1
CREATE PARTITION SCHEME Ps_Range
AS PARTITION Pt_Range
TO (Group1, Group2, Group3, Group4);---04创建表,指定的分区列的数据类型一定要和分区函数指定的列类型一致。
CREATE TABLE [dbo].[News]([id] [bigint] NOT NULL,[status] [int] NULL,CONSTRAINT [PK_News] PRIMARY KEY CLUSTERED
([id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Ps_Range](id)
) ON [Ps_Range](id)-----创建归档分区表
CREATE TABLE [dbo].[NewsArchived]([id] [bigint] NOT NULL,[status] [int] NULL,CONSTRAINT [PK_NewsArchived] PRIMARY KEY CLUSTERED
([id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Ps_Range](id)
) ON [Ps_Range](id)----插入测试数据
DECLARE @id INT
SET @id=1
WHILE @id<5001000
BEGININSERT INTO News VALUES(@id,@id%2)SET @id=@id+1END

可以看到当前总共有4个分区,每一个分区定义的范围区间是100万,分区4我故意多插入了200多万的数据来验证自动归档分区。

二、自动归档分区脚本

CREATE PROCEDURE Pro_Partition_AutoArchiveData
(@PartitionTable VARCHAR(300),
@SwitchTable VARCHAR(300)
)
AS
BEGIN
DECLARE @FunName VARCHAR(100),@SchemaName VARCHAR(100),@MaxPartitionValue sql_variant---根据归档表查找对应的分区方案、分区函数、最小分区数、最大分区范围值
SELECT
DISTINCT
@FunName=MAX(pf.name),
@SchemaName=MAX(ps.name),
@MaxPartitionValue=max(isnull(prv.value,0))
FROM sys.partitions  p inner join sys.indexes i ON p.object_id=i.object_id and p.index_id=i.index_id
inner join sys.partition_schemes ps ON i.data_space_id=ps.data_space_id
inner join sys.destination_data_spaces dds ON ps.data_space_id=dds.partition_scheme_id and dds.destination_id=p.partition_number
inner join sys.data_spaces ds ON dds.data_space_id=ds.data_space_id
inner join sys.partition_functions pf ON ps.function_id=pf.function_id
LEFT join sys.partition_range_values prv ON pf.function_id=prv.function_id AND prv.boundary_id=p.partition_number-pf.boundary_value_on_right
LEFT join sys.partition_parameters pp ON prv.function_id=pp.function_id and prv.parameter_id=pp.parameter_id
LEFT join sys.types t ON pp.system_type_id=t.system_type_id and pp.user_type_id=t.user_type_id
WHERE OBJECT_NAME(p.OBJECT_ID)=@PartitionTableDECLARE @MaxId BIGINT,@MinId BIGINT,@Sql NVARCHAR(MAX),@GroupName VARCHAR(100),@MinPartitionNumber INT
SET @Sql= N'SELECT @MaxId=MAX(id),@MinId=Min(id) FROM '+@PartitionTable
EXEC sp_executesql @Sql,N'@MaxId BIGINT out,@MinId BIGINT out',@MaxId OUT,@MinId OUTSELECT @FunName AS FunName,@SchemaName AS SchemaName,@MaxPartitionValue AS MaxPartitionValue ,@MaxId AS MaxId,@MinId AS MinId---判断当前表的最大的id是否已经在最大的分区中
IF @MaxId>=@MaxPartitionValueBEGIN----归档分区数据,根据表的最小值找到它所属的分区.SET @Sql= N'SELECT @MinPartitionNumber=$PARTITION.'+@FunName+N'('+CONVERT(VARCHAR(30),@MinId)+N')';EXEC sp_executesql @Sql,N'@MinPartitionNumber INT out',@MinPartitionNumber OUTSET @Sql=N'ALTER TABLE ' +@PartitionTable+ N' SWITCH PARTITION '+CONVERT(VARCHAR(10),@MinPartitionNumber)+ N' TO ' +@SwitchTable+ N' PARTITION ' +CONVERT(VARCHAR(10),@MinPartitionNumber);--PRINT @SqlEXEC (@Sql)---修改分区方案,增加新的分区对应的文件组,根据最小的分区id找到对应的文件组。SELECT DISTINCT@GroupName=ds.nameFROM sys.partitions  p inner join sys.indexes i ON p.object_id=i.object_id and p.index_id=i.index_idinner join sys.partition_schemes ps ON i.data_space_id=ps.data_space_idinner join sys.destination_data_spaces dds ON ps.data_space_id=dds.partition_scheme_id and dds.destination_id=p.partition_numberinner join sys.data_spaces ds ON dds.data_space_id=ds.data_space_idinner join sys.partition_functions pf ON ps.function_id=pf.function_idWHERE pf.name=@FunName AND ps.name=@SchemaName AND p.partition_number=@MinPartitionNumberSET @Sql=N'ALTER PARTITION SCHEME '+@SchemaName+N' NEXT USED '+@GroupName--PRINT @SqlEXEC (@Sql)---修改分区函数,增加新的分区,增加新的分区范围值,在现有的最大的值的基础上加100万(需要和现有的分区函数的范围保持一致)SET @MaxPartitionValue=CONVERT(BIGINT,@MaxPartitionValue)+1000000SET @Sql=N'ALTER PARTITION FUNCTION '+@FunName+N'('+N')'+N' SPLIT RANGE ('+CONVERT(VARCHAR(30),@MaxPartitionValue)+N')'--PRINT @SqlEXEC (@Sql)ENDEND

三、自动归档分区数据

1.首次测试

EXEC Pro_Partition_AutoArchiveData 'news','NewsArchived';

注意:每调用一次归档一个最小分区的数据。

分区表的News分区1的数据被归档到了NewsArchived表中,且创建了分区5,分区5使用的是已归档的分区1的文件组,达到了循环利用文件组的效果。

2.再调用一次归档分区脚本

当分区表最大的id小于最大的分区值时自动归档分区脚本就不会生效。所以当前的测试表数据还可以再归档分区3的数据。

3.经过一段时间的运行归档数据可能是这样的效果

Group1→Group4→Group1→.......

四、脚本注意事项

1.@PartitionTable和@SwitchTable表必须使用同名的分区方案和分区函数,否则@SwitchTable就需要单独修改分区方案和函数,且表结构完全一致。
2.归档的表分区列数据类型必须是INT类型,且值是自增规律.
3.分区归档作业在备份作业后执行
4.建议使用Right分区,Left分区会出现有的最后一个分区文件组不会循环替换,一直处于分区的最后,比如Group1,Group2,Group3,Group1,Group2,Group3,Group1,Group4。期望的应该是Group1,Group2,Group3,Group4,Group1,Group2,Group3,Group4,Group1
5.注意我当前的每个分区大小是100万和分区函数保持一致,如果范围值不同,需要修改最末尾代码的"修改分区函数"处代码.

总结

当前自动归档分区脚本如果要拷贝去用还是得能完全理解每一段代码,根据自己的业务做适当的修改,毕竟数据是无价的!!!。最后只需要创建一个作业定期跑作业就行,重复执行也不影响。

备注:

作者:pursuer.chen

博客:http://www.cnblogs.com/chenmh

本站点所有随笔都是原创,欢迎大家转载;但转载时必须注明文章来源,且在文章开头明显处给明链接,否则保留追究责任的权利。

《欢迎交流讨论》

posted on 2018-01-25 08:55 NET未来之路 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/8349498.html

SQL Server 自动循环归档分区数据脚本相关推荐

  1. 【Transact-SQL】SQL Server自动把left join自动转化为inner join、以及关联时的数据重复问题...

    1.SQL Server自动把left join自动转化为inner join的问题: 下面的两个语句都是left join的,但是一个却转化成了 inner join drop table a,B ...

  2. 清空SQL Server数据库中所有表数据的方法(转)

    清空SQL Server数据库中所有表数据的方法 其实删除数据库中数据的方法并不复杂,为什么我还要多此一举呢,一是我这里介绍的是删除数据库的所有数据,因为数据之间可能形成相互约束关系,删除操作可能陷入 ...

  3. Sql Server函数全解三数据类型转换函数和文本图像函数

    原文:Sql Server函数全解<三>数据类型转换函数和文本图像函数 一:数据类型转换函数 在同时处理不同数据类型的值时,SQL Server一般会自动进行隐士类型转换.对于数据类型相近 ...

  4. SQL Server 自动更新统计信息的基本算法

    最初接触SQL Server的时候认为SQLServer数据更改的同时就会相应的更新统计信息,其实SQL Server不是这样做的.基于性能考虑,SQL Server使用下面的算法更新统计信息. 自动 ...

  5. SQL Server报表生成器中的R脚本词云

    什么是R (What is R) R is a very popular data programing language. R is especially used in data analysis ...

  6. CREATE VIEW SQL:通过SQL Server中的视图插入数据

    This is the third article in a series of learning the CREATE VIEW SQL statement. So far, I'd say tha ...

  7. SQL截断增强功能:SQL Server 2019中的静默数据截断

    In this article, we'll take a look into SQL truncate improvement in SQL Server 2019. 在本文中,我们将研究SQL S ...

  8. char varchar nchar nvarchar 四者的区别是什么(为何SQL Server自动给字符串末尾加空格)...

    本着低碳的原则将几个变量声明为nchar,结果发现尾巴上每次都多一大串空格,C#中不得不多次Trim劳心费神易出错.上网一查原来四种字符串看似相近其实讲究很多,其中以本帖最为全面,特此转发. 原帖:h ...

  9. MS SQL Server:分区表、分区索引详解

    MS SQL Server:分区表.分区索引 详解 1. 分区表简介 使用分区表的主要目的,是为了改善大型表以及具有各种访问模式的表的可伸缩性和可管理性.  大型表:数据量巨大的表.  访问模式: ...

最新文章

  1. Go 语言编程 — 数据类型转换
  2. Lingo 优化实例 出版社问题
  3. C#程序出现内存溢出错误的解决办法
  4. 【Java数据库】SQL时间类型Date Time Timestamp区别、插入/取出指定时间段的数据
  5. SAP Spartacus org unit页面的三种focus border及细节讨论
  6. java反射机制+继承设计技巧
  7. 看FusionInsight Spark如何支持JDBCServer的多实例特性
  8. “寒门状元之死”文章引热议 京东徐雷:三流文学作品 多看书吧
  9. 计算机网络学习笔记(14. OSI参考模型②)
  10. hbase针对fullgc所做的优化(Memstore所作的优化 针对BlockCache所作优化)
  11. 计算机控制实验 实验十,自控计控原理实验箱
  12. 加减乘除求余 利用 位运算实现(详细)
  13. 徐思/杨玲《面向对象程序设计(Java)》第十一周学习总结
  14. 【开发环境】Ubuntu 安装 Visual Studio Code 开发环境 ( 下载 Visual Studio Code 安装器 | Ubuntu 安装 deb 包 )
  15. 着色Shading(1)(光照、着色)(笔记)
  16. u盘占内存,却找不见内容
  17. 05 linux shell脚本 变量的取用echo;变量的设置和修改;变量的使用规范以及示例
  18. Python pandas,index索引,修改索引,复合索引,将某列设为索引
  19. 本体开发日记03-理解代码
  20. 【Ctrl_I】团队日记2:模型训练与HIbernate集成

热门文章

  1. php输出echo、print、print_r、printf、sprintf、var_dump比较
  2. LeetCode之Max Points on a Line Total
  3. Sql中对大数据量的判断
  4. React基础篇(六)React中绑定事件的注意点
  5. [Ting's笔记Day6]活用套件carrierwave gem:(1)在Rails实现图片上传功能
  6. jQuery——子元素筛选器
  7. ANSI C、ISO C、Standard C联系与区别
  8. 转载:javascript中定义兑现改的5种方式
  9. CDQZ_Training 2012-05-24 聪明的打字员
  10. 十大非著名之父:手机,黑莓,iPod,FORTRAN,远程办公,鼠标,垃圾邮件,DSL,Java,WIFI说,我爸是...-asp.net关注...