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操作归档分区表 ...
随机推荐
- 消息队列——RabbitMQ学习笔记
消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...
- java中的锁
java中有哪些锁 这个问题在我看了一遍<java并发编程>后尽然无法回答,说明自己对于锁的概念了解的不够.于是再次翻看了一下书里的内容,突然有点打开脑门的感觉.看来确实是要学习的最好方式 ...
- 【探索】利用 canvas 实现数据压缩
前言 HTTP 支持 GZip 压缩,可节省不少传输资源.但遗憾的是,只有下载才有,上传并不支持.如果上传也能压缩,那就完美了.特别适合大量文本提交的场合,比如博客园,就是很好的例子. 虽然标准不支持 ...
- ASP.NET Aries 入门开发教程7:DataGrid的行操作(主键操作区)
前言: 抓紧勤奋,再接再励,预计共10篇来结束这个系列. 上一篇介绍:ASP.NET Aries 入门开发教程6:列表数据表格的格式化处理及行内编辑 本篇介绍主键操作区相关内容. 1:什么时候有默认的 ...
- MVC Core 网站开发(Ninesky) 2.1、栏目的前台显示(补充)
在2.1.栏目的前台显示中因右键没有添加视图把微软给鄙视了一下,后来有仔细研究了一下发现应该鄙视自己,其实这个功能是有的,是自己没搞清楚乱吐糟. 其实只要在NuGet中安装两个包(Microsoft. ...
- dubbox微服务实例及引发的“血案”
Dubbo 是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成. 主要核心部件: Remoting: 网络通信框架 ...
- [开发笔记] Graph Databases on developing
TimeWall is a graph databases github It be used to apply mathematic model and social network with gr ...
- jquery学习(一)
简单的jquery学习,首先在页面引入jquery <!-- 引入jquery --> <script src="js/jquery-1.8.3.js" type ...
- 非技术1-学期总结&ending 2016
好久好久没写博客了,感觉动力都不足了--12月只发了一篇博客,好惭愧-- 今天是2016年最后一天,怎么能不写点东西呢!! 学期总结 大学中最关键一年的第一个学期,共4个月.前20天在学网络方面的,当 ...
- (转载) Linux IO模式及 select、poll、epoll详解
注:本文是对众多博客的学习和总结,可能存在理解错误.请带着怀疑的眼光,同时如果有错误希望能指出. 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案 ...