Partition:增加分区
在关系型 DB中,分区表经常使用DateKey(int 数据类型)作为Partition Column,每个月的数据填充到同一个Partition中,由于在Fore-End呈现的报表大多数是基于Month的查询,按照Month分区的设计能够提高查询性能,但是,如果,前任DBA没有创建Schedule来维护Partition Function,不能增加新的Partition,所有新增加的数据都会插入到最后一个Partition中,导致最后一个Partition填充的数据量十分大,降低了分区表的查询性能。
一,最佳实践(Best Practices )
微软建议,避免对已填充的分区执行split或merge操作。在分区表的两端都保持空的分区(Empty Partition),第一个分区和最后一个分区是Empty Partition。通过对尾端的Empty Partition进行Split操作,就能在尾端增加分区,并且不会产生数据移动;当将数据从前端的第二个分区中归档后,第一个分区和第二个分区都是Empty Partition,Empty Partition进行Merge操作,不会产生数据的移动。
Always keep empty partitions at both ends of the partition range to guarantee that the partition split (before loading new data) and partition merge (after unloading old data) do not incur any data movement. Avoid splitting or merging populated partitions. This can be extremely inefficient, as this may cause as much as four times more log generation, and may also cause severe locking.
因此,受此Best Practices的影响,DB开发人员在创建分区表时,一般的做法是只创建特定数量的分区,并且只保持两端是Empty Partition,例如:
CREATE PARTITION FUNCTION [funcPartition_DateKey](int)
AS RANGE RIGHT
FOR VALUES (20100701, 20100801, <.....> , 20150501, 20150601)
GO CREATE PARTITION SCHEME [schePartition_DataKey]
AS PARTITION [funcPartition_DateKey]
TO ([PRIMARY], <....>, [PRIMARY])
GO
改进建议:在SQL Server 2012中,在一个Table或索引上,最多能够创建15 000个分区(In SQL Server 2012, a table or index can have a maximum of 15,000 partitions),未雨绸缪,我们可以按照月份,一次性创建360个分区,每月一个分区,每年12个分区,服务30年,一劳永逸,当然,也可以创建Schedule,前提是,你必须保证Schedule按时执行成功。
如果,必须要对已填充的分区表,增加分区,要怎么做?
方法1,直接修改Partition Function,通过拆分末端Partition来增加分区
由于很多 Big Table 使用相同的Partition Schema进行分区,简单地从末端Partition为起点,逐个增加分区,在短时间内会产生海量的Disk IO操作,对系统产生极大的影响,例如
declare @DateKey int
set @DateKey=20150701 while @DateKey<20200101
begin
alter partition scheme [schePartition_DataKey]
Next Used [primary];
alter partition function [funcPartition_DateKey]()
split range(@DateKey);
set @DateKey=cast(convert(nvarchar(8),dateadd(month,1,cast(cast(@DateKey as nvarchar(8)) as date)),112) as int);
end
方法2,更改分区表的Partition Schema
创建新的Partition function 和 Partition Schema,逐个Table修改其Partition Schema,这个方法(Workaround),虽然实现过程比较繁琐,但是对系统性能的副作用最小,将影响控制在当前操作的Target Table。
Script1,创建新的Partition设计
--create Partition function
declare @DateKeyList varchar(max)
declare @DateKey int
--set initial DateKey
set @DateKey=20140701;
while @DateKey<20200101
begin
set @DateKeyList=coalesce(@DateKeyList+','+cast(@DateKey as varchar(8)),cast(@DateKey as varchar(8)))
--Increase iterator
set @DateKey=cast(convert(nvarchar(8),dateadd(month,1,cast(cast(@DateKey as nvarchar(8)) as date)),112) as int);
end
--print DateKey List
--select @DateKeyList
declare @sql nvarchar(max)
set @sql=N'
CREATE PARTITION FUNCTION [funcPartition_new_DateKey](int)
AS RANGE RIGHT
FOR VALUES ('+@DateKeyList+N');' EXEC sys.sp_executesql @sql
GO
--create partition schema
CREATE PARTITION SCHEME [schePartition_new_DataKey]
AS PARTITION [funcPartition_new_DateKey]
all TO ([PRIMARY]);
GO
Script2,逐个更新Table的Patition Schema
由于Patition Table中,可能存在不止一个Index,在rebuild table时,使用 drop_existing=on 能够减少分区表上nonclustered indexes的重建时间。
--rebuild table
create unique clustered index [PK__SchemaName_TableName_KeyColumn]
on SchemaName.TableName([KeyColumn],[CreatedDateKey])
with(data_compression=page,drop_existing=on)
on [schePartition_new_DataKey]([CreatedDateKey]); --rebuild columnstore index
CREATE NONCLUSTERED COLUMNSTORE INDEX [idx_ColumnStore_SchemaName_TableName]
ON [SchemaName].[TableName]
(
column list....
)
三,在同一个文件组中创建分区
在一个文件组中创建表的所有分区,每个分区在物理上都是独立的存储对象,只不过这些独立的存储对象位于同一个FileGroup。
1,创建Patition Schema时,使用 ALL 关键字指定只能指定一个FileGroup,所有的Partition 都创建在同一个FileGroup上;在Patition Schema创建成功之后,默认会将该FileGroup标记为Next Used
ALL Specifies that all partitions map to the filegroup provided in file_group_name, or to the primary filegroup if [PRIMARY] is specified. If ALL is specified, only one file_group_name can be specified.
If [PRIMARY] is specified, the partition is stored on the primary filegroup. If ALL is specified, only one file_group_name can be specified. Partitions are assigned to filegroups, starting with partition 1, in the order in which the filegroups are listed in [,...n]. The same file_group_name can be specified more than one time in [,...n].
2,在Patition schema中,只有一个FileGroup会被指定(Mark)为Next Used
如果FileGroup被指定为Next Used,意味着分区表的下一个分区将会创建在该FileGroup上。在创建Patition Schema时,指定 ALL关键字,不仅指定将表的所有分区都创建在同一个FileGroup上,而且,还将该FileGroup指定为Next Used。
If ALL is specified, the sole file_group_name maintains its NEXT USED property for this partition_function_name. The NEXT USED filegroup will receive an additional partition if one is created in an ALTER PARTITION FUNCTION statement.
3,在执行Patition Split 操作时,必须存在一个FileGroup被指定为Next Used,否则,Split 操作失败
在指定Next Used时,要注意:
- 在创建Partition Scheme时,指定ALL关键字,只会将一个FileGroup指定为Next Used;
- 可以多次指定Next Used,最后一次指定的FileGroup是Next Used;
- 一个FileGroup可以被多次指定为Next Used;即使该File Group已经用于存储(Hold)分区的数据; A filegroup that already holds partitions can be designated to hold additional partitions.
- 在完成一次Partition Split操作之后,之前的Next Used 已被使用,当前不存在被指定为Next Used的FileGroup,必须显式指定一个FileGroup作为新的Next Used,才能继续执行Partition Split操作;
If you create all the partitions in the same filegroup, that filegroup is initially assigned to be the NEXT USED filegroup automatically. However, after a split operation is performed, there is no longer a designated NEXT USED filegroup. You must explicitly assign the filegroup to be the NEXT USED filegroup by using ALTER PARITION SCHEME or a subsequent split operation will fail.
显式将一个FileGroup 指定为 Next Used
ALTER PARTITION SCHEME partition_scheme_name
NEXT USED [ filegroup_name ] [ ; ]
Appendix
使用Alter Partition Function 命令执行拆分或合并分区的操作,每次操作,只能拆分一个,或合并一个分区:
ALTER PARTITION FUNCTION partition_function_name()
{
SPLIT RANGE ( boundary_value )
| MERGE RANGE ( boundary_value )
} [ ; ]
ALTER PARTITION FUNCTION repartitions any tables and indexes that use the function in a single atomic operation. However, this operation occurs offline, and depending on the extent of repartitioning, may be resource-intensive.
参考doc:
Rebuilding Existing Partitioned Tables to a New Partition Scheme
ALTER PARTITION FUNCTION (Transact-SQL)
ALTER PARTITION SCHEME (Transact-SQL)
Partition:增加分区的更多相关文章
- MySQL每天自动增加分区
有一个表tb_3a_huandan_detail,每天有300W左右的数据.查询太慢了,网上了解了一下,可以做表分区.由于数据较大,所以决定做定时任务每天执行存过自动进行分区. 1.在进行自动增加分区 ...
- Partition4:增加分区
在关系型 DB中,分区表经常使用DateKey(int 数据类型)作为Partition Column,每个月的数据填充到同一个Partition中,由于在Fore-End呈现的报表大多数是基于Mon ...
- [Linux] - Virtualbox-CentOS动态增加分区空间方法
VirtualBox使用中,有时会因为当初分配空间不足导致出问题,可以使用如下方式增加分区空间: 一.VirtualBox设置: 1)到VirtualBox的安装目录下找到这个命令exe文件:vbox ...
- kafka partition(分区)与 group
kafka partition(分区)与 group 一. 1.原理图 2.原理描述 一个topic 可以配置几个partition,produce发送的消息分发到不同的partition中,co ...
- CAP理论中, P(partition tolerance, 分区容错性)的合理解释
在CAP理论中, 对partition tolerance分区容错性的解释一般指的是分布式网络中部分网络不可用时, 系统依然正常对外提供服务, 而传统的系统设计中往往将这个放在最后一位. 这篇文章对这 ...
- DBA_Oracle Table Partition表分区概念汇总(概念)
2014-06-20 Created By BaoXinjian
- [转]mysql在已有无分区表增加分区,mysql5.5才有,可以是innodb_file_per_table关闭状态.
FROM : http://blog.csdn.net/sunvince/article/details/7752662 mysql5.1的时候新增的partition,解决了比较简单的shardin ...
- zabbix mysql 迁移 增加分区
1.zabbix mysql 目录清单 --basedir=/usr/local/web/mysql --datadir=/data/mysql --log-error=/data/mysql/sys ...
- Partition:分区切换(Switch)
在SQL Server中,对超级大表做数据归档,使用select和delete命令是十分耗费CPU时间和Disk空间的,SQL Server必须记录相应数量的事务日志,而使用switch操作归档分区表 ...
随机推荐
- boost强分类器的实现
boost.cpp文件下: bool CvCascadeBoost::train( const CvFeatureEvaluator* _featureEvaluator, int _numSampl ...
- 2015 西雅图微软总部MVP峰会记录
2015 西雅图微软总部MVP峰会记录 今年决定参加微软MVP全球峰会,在出发之前本人就已经写这篇博客,希望将本次会议原汁原味奉献给大家 因为这次是本人第一次写会议记录,写得不好的地方希望各位园友见谅 ...
- MVVM设计模式和WPF中的实现(四)事件绑定
MVVM设计模式和在WPF中的实现(四) 事件绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...
- premere cs4绿色版 安装 并且 视频导出 讲解
最近室友,开始在玩视频剪辑,用的是 premere cs4 绿色版.让他遇到的最大问题也是我之前遇到的最大问题,就是视频导出. 所以我在这里上传一套自己的一点点经验吧. 接下来,我就总结一下 我是怎么 ...
- 旺财速啃H5框架之Bootstrap(一)
接下来的时间里,我将和大家一起对当前非常流行的前端框架Bootstrap进行速度的学习,以案例的形式.对刚开始想学习Bootstrap的同学而找不着边的就很有帮助了.如果你想详细的学习Bootstra ...
- javascript 判断参数类型大全
js 判断类型的在开发中是很常用的,因为js 是弱类型的语言,var 可以接受任何形式的类型,但是在真正的开发中,我们需要根据不同类型做不同的处理,所以这个是必须的精通. 首先需要知道 typeof这 ...
- jquery屏幕滚动计算事件总结
获取浏览器显示区域(可视区域)的高度 : $(window).height(); 获取浏览器显示区域(可视区域)的宽度 : $(window).width(); 获取页面的文档高度: $(docume ...
- 初识JavaScript
JavaScript ECMA-262: 变量,函数,对象,数据类型....唯独没有输入和输出. Javascript:包含 ECMA-262,核心 BOM 浏览器对象模型, DOM 文档对象模型 什 ...
- Sass之坑Compass编译报错
前段时间在使用Compass时遇到了其为难处理的一个坑,现记录到博客希望能帮助到各位. 一.问题: 利用Koala或者是gulp编译提示如下,截图为koala编译提示错误: 二.解决办法 从问题截图上 ...
- jquery-treegrid树状表格的使用(.Net平台)
上一篇介绍了DataTable,这一篇在DT的基础之上再使用jquery的一款插件:treegrid,官网地址:http://maxazan.github.io/jquery-treegrid/ 一. ...