设为首页 收藏本站
查看: 1818|回复: 0

[经验分享] SQL SERVER分区具体例子详解

[复制链接]

尚未签到

发表于 2017-7-12 20:00:34 | 显示全部楼层 |阅读模式
  在日常工作中,我们会遇到以下的情况,一个表每日数万级的增长,而查询的数据通常是在本月或今年,以前的数据偶尔会用到,但查询和插入的效率越来越慢,用数据库分区会有助于解决这个问题。关于分区的理论知识网上很多我这里就不在累赘,我从一个实际例子出发,看如何将一个已经运行了很长时间的普通表进行分区。

提出问题

  需解决问题:有一个数据表数据很大,我们通常的查询是在一个季度中。我们需要将以往年份的数据按不同年份存在文件组里,当年的数据分为4个季度存,如果到了新的一年,将之前4个季度的合并到一年中,新的一年又按4个季度分区。


解决问题
  好了我们将一步步的开始解决问题。

建立模拟环境
  1.首先建立数据库,和创建表。
DSC0000.png

  新建个数据库,新建测试表。数据文件放在一个好找的文件夹内,方便分区文件一并放在其中。
  2.创建模拟数据。
  我用C#程序模拟插入了一些数据,时间从2015-9-1号到2017-4-1每天一天数据。此时表的属性如下,文件组Primary,未分区。
DSC0001.png


建立分区文件
DSC0002.png

  新建5个文件组,对应5个数据库文件,Y2015存放2015年的数据,Q1,Q2,Q3,Q4存放4个季度的数据,这里我们将文件都放在了同一个文件夹,如果条件允许,放在不同的磁盘上会增加读写效率。

建立分区函数
  分区函数RANGE有区分LEFT和RIGHT
  
LEFT是第一个分区小于等于边界,第二个分区大于
  
RIGHT是第一个分区小于边界,第二个分区大于等于
CREATE PARTITION FUNCTION [PartitionFunc](datetime) AS RANGE RIGHT FOR VALUES (N'2016-01-01T00:00:00', N'2016-04-01T00:00:00',N'2016-07-01T00:00:00',N'2016-10-01T00:00:00',N'2017-01-01T00:00:00')
建立分区方案
  这个分区函数将分为6个文件组
CREATE PARTITION SCHEME [PartitionScheme] AS PARTITION [PartitionFunc] TO ([Y2015], [Q1],[Q2],[Q3],[Q4],[PRIMARY])  建立好的分区函数和分区方案如下:
  
DSC0003.png

建立分区索引完成分区
  分区索引必须是聚集索引,我们建标时用SQL里的主键设置会自动将ID设置为聚集索引这里我们需要把原先的主键改为分聚集索引,在建立分区索引。
CREATE CLUSTERED INDEX [ClusteredIndex_CreateDate] ON [dbo].[SchemTest]  
(
  [CreateDate]
  
)WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PartitionScheme]([CreateDate])
  这样表分区就完成了。
DSC0004.png


查询分区中的数据
  我们可以查下在不同分区中的数据,语句如下:
select $PARTITION.PartitionFunc(CreateDate) as 分区编号,count(ID) as 记录数 from SchemTest group by $PARTITION.PartitionFunc(CreateDate)  
DSC0005.png

select * from SchemTest where $PARTITION.PartitionFunc(CreateDate)=1    这样查询所有2015年的数据。

分区新增和合并
  现在 2015年的数据在2015文件组,2016年数据在4个季度的文件组,2017年数据在Primary的文件组,现在要将2016年的数据放在新增的2016文件组,4个季度的文件组放2017年的数据,Primary放2018年后的。
  1.新建2016的文件组
  
DSC0006.png
  2.分区合并
  
先将所有季度文件组都合并,这样2017年数据之前都在2015文件组
ALTER PARTITION FUNCTION PartitionFunc() MERGE RANGE (N'2016-01-01T00:00:00');  
ALTER PARTITION FUNCTION PartitionFunc() MERGE RANGE (N'2016-04-01T00:00:00');  
  
ALTER PARTITION FUNCTION PartitionFunc() MERGE RANGE (N'2016-07-01T00:00:00');  
  
ALTER PARTITION FUNCTION PartitionFunc() MERGE RANGE (N'2016-10-01T00:00:00');  
  可以在分区方案上查看创建SQL语句,这时的分区方案已经更改为:
CREATE PARTITION SCHEME [PartitionScheme] AS PARTITION [PartitionFunc] TO ([Y2015], [PRIMARY])  3.分区新增
  首先将2016年的数据放在Y2016文件组
--选择文件组  
ALTER PARTITION SCHEME PartitionScheme  
  
NEXT USED [Y2016] ;
  
--修改分区函数  
  
ALTER PARTITION FUNCTION PartitionFunc()  
  
SPLIT RANGE (N'2016-01-01T00:00:00.000') ;
  同理将2017年的数据分别放在2017年的各个季度中
ALTER PARTITION FUNCTION PartitionFunc()  MERGE RANGE (N'2017-01-01T00:00:00');  
ALTER PARTITION SCHEME PartitionScheme  NEXT USED [Q1] ;
  
ALTER PARTITION FUNCTION PartitionFunc()  SPLIT RANGE (N'2017-01-01T00:00:00.000') ;
  
ALTER PARTITION SCHEME PartitionScheme  NEXT USED [Q2] ;
  
ALTER PARTITION FUNCTION PartitionFunc()  SPLIT RANGE (N'2017-04-01T00:00:00.000') ;
  
ALTER PARTITION SCHEME PartitionScheme  NEXT USED [Q3] ;
  
ALTER PARTITION FUNCTION PartitionFunc()  SPLIT RANGE (N'2017-07-01T00:00:00.000') ;
  
ALTER PARTITION SCHEME PartitionScheme  NEXT USED [Q4] ;
  
ALTER PARTITION FUNCTION PartitionFunc()  SPLIT RANGE (N'2017-10-01T00:00:00.000') ;
  
ALTER PARTITION SCHEME PartitionScheme  NEXT USED [PRIMARY] ;
  
ALTER PARTITION FUNCTION PartitionFunc()  SPLIT RANGE (N'2018-01-01T00:00:00.000') ;
  现在查看分区函数和分区方案的创建语句如下:
CREATE PARTITION SCHEME [PartitionScheme] AS PARTITION [PartitionFunc] TO ([Y2015], [Y2016], [Q1], [Q2], [Q3], [Q4], [PRIMARY])  
CREATE PARTITION FUNCTION [PartitionFunc](datetime) AS RANGE RIGHT FOR VALUES (N'2016-01-01T00:00:00.000', N'2017-01-01T00:00:00.000', N'2017-04-01T00:00:00.000', N'2017-07-01T00:00:00.000', N'2017-10-01T00:00:00.000', N'2018-01-01T00:00:00.000')
  分区记录如下:
  
DSC0007.png
  如果分区变动比较大不推荐用合并和删除的方法,因为容易出错,如果分12个月建议像下面一样,先将分区表转换为普通表,再把普通表分区。

将分区表转换成普通表
  1.删除分区索引
  删除分区索引后,并没有编程普通表
DSC0008.png

  2.在原有分区索引字段,建立普通索引
CREATE CLUSTERED INDEX [IX_SchemTest]  ON SchemTest(CreateDate) ON [Primary]
DSC0009.png

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-393290-1-1.html 上篇帖子: SQL Server-简单查询示例(十一) 下篇帖子: sql server实现自定义分割月功能
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表