`
baobaojinjin
  • 浏览: 142124 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

SQL Server 2008 分区函数和分区表详解

 
阅读更多

当我们数据量比较大的时候,我们需要将大型表拆分为多个较小的表,则只访问部门数据的查询就可以更快的运行,基本原理就是,因为要扫描的数据变的更小。维护任务(例如,重新生成索引或备份表)也可以更快的运行。

我们可以再不通过将表物理放置在多个磁盘驱动器上来拆分表的情况下获取分区。如果将某个表放置在一个物理驱动器上,将相关表放置在另一个驱动器上,则可以提高查询性能,因为当运行涉及表间连接的查询时,多个磁盘头同时读取数据。可以使用SQL Server文件组来指定放置表的磁盘。

对于分区的方式,基本就三种方式:硬件分区、水平分区、垂直分区。相关方案可以参考SQL联机丛书。

这里我们介绍分区表的具体实战方法:

第一步,首先建立我们要使用的数据库,最重要的是建立多个文件组。

我们先新建立四个目录,来组成文件组,一个用来存放主文件的目录:Primary

三个数据文件目录:FG1、FG2、FG3

建立库:

 

1 create database Sales on primary
2 (
3 name=N'Sales',
4 filename=N'G:\data\Primary\Sales.mdf',
5 size=3MB,
6 maxsize=100MB,
7 filegrowth=10%
8 ),
9 filegroup FG1
10 (
11 NAME = N'File1',
12 FILENAME = N'G:\data\FG1\File1.ndf',
13 SIZE = 1MB,
14 MAXSIZE = 100MB,
15 FILEGROWTH = 10%
16 ),
17 FILEGROUP FG2
18 (
19 NAME = N'File2',
20 FILENAME = N'G:\data\FG2\File2.ndf',
21 SIZE = 1MB,
22 MAXSIZE = 100MB,
23 FILEGROWTH = 10%
24 ),
25 FILEGROUP FG3
26 (
27 NAME = N'File3',
28 FILENAME = N'G:\data\FG3\File3.ndf',
29 SIZE = 1MB,
30 MAXSIZE = 100MB,
31 FILEGROWTH = 10%
32 )
33 LOG ON
34 (
35 NAME = N'Sales_Log',
36 FILENAME = N'G:\data\Primary\Sales_Log.ldf',
37 SIZE = 1MB,
38 MAXSIZE = 100MB,
39 FILEGROWTH = 10%
40 )
41 GO

 

第二步:建立分区函数,目的是用来规范不同数据存放到不同目录的标准,简单讲就是如何分区。

 

1 USE Sales
2 GO
3 CREATE PARTITION FUNCTION pf_OrderDate (datetime)
4 AS RANGE RIGHT
5 FOR VALUES ('2003/01/01', '2004/01/01')
6 GO

 

我们创建了一个用于数据类型为datetime的分区函数,按照时间段来划分。

文件组 分区 取值范围
FG1 1 (过去某年, 2003/01/01)
FG2 2 [2003/01/01, 2004/01/01)
FG3 3 [2004/01/01,未来某年)

第三步:创建分区方案,关联到分区函数。目的就是我们将已经建立好的分区函数组织成一套方案,简单点将就是我们在哪里对数据进行分区。

 

1 Use Sales
2 go
3 create partition scheme ps_OrderDate
4 as partition pf_OrderDate
5 to(FG2,FG2,FG3)
6 go

 

很简单,就是将第二步建立的分区函数应用已经建立的分区组中。

第四步:创建分区表。创建表并将其绑定到分区方案上。我们首先建立两个表,一张原始表另一张用来归档数据,保存归档数据。

 

1 Use Sales
2 go
3 create table Orders
4 (
5 OrderID int identity(10000,1),
6 OrderDate datetime not null,
7 CustomerID int not null,
8 constraint PK_Orders primary key(OrderID,OrderDate)
9 )
10 on ps_OrderDate(OrderDate)
11 go
12 create table OrdersHistory
13 (
14 OrderID int identity(10000,1),
15 OrderDate datetime not null,
16 CustomerID int not null,
17 constraint PK_OrdersHistory primary key(OrderID,OrderDate)
18 )
19 on ps_OrderDate(OrderDate)
20 go

 

到这里,通过上面的四步我们已经完整的搭建好了一个带有分区表的库,我们来插入一些数据,来测试下我们建立是否好用。

首先,因为是用2003年1月1号作为区分点的,我们先向数据表中写入2002年的规范数据:

 

1 USE Sales
2 GO
3 INSERT INTO dbo.Orders (OrderDate, CustomerID) VALUES ('2002/6/25', 1000)
4 INSERT INTO dbo.Orders (OrderDate, CustomerID) VALUES ('2002/8/13', 1000)
5 INSERT INTO dbo.Orders (OrderDate, CustomerID) VALUES ('2002/8/25', 1000)
6 INSERT INTO dbo.Orders (OrderDate, CustomerID) VALUES ('2002/9/23', 1000)
7 GO

 

同样我们写入2003年四条数据:

 

1 USE Sales
2 GO
3 INSERT INTO dbo.Orders (OrderDate, CustomerID) VALUES ('2003/6/25', 1000)
4 INSERT INTO dbo.Orders (OrderDate, CustomerID) VALUES ('2003/8/13', 1000)
5 INSERT INTO dbo.Orders (OrderDate, CustomerID) VALUES ('2003/8/25', 1000)
6 INSERT INTO dbo.Orders (OrderDate, CustomerID) VALUES ('2003/9/23', 1000)
7 GO

 

我们来查看这些数据是否完整录入:

SQL Server 2008 分区函数和分区表

因为OrdersHistory表我们还没有归档数据,所以为空。

我们来分条件查询下:

1、查询某个分区

这里我们要用到$partition函数。这个函数在联机丛书中是这样解释的:

用法:
为任何指定的分区函数返回分区号,一组分区列值将映射到该分区号中。
语法: 
[ database_name. ] $PARTITION.partition_function_name(expression)
参数:
database_name 
包含分区函数的数据库的名称。
partition_function_name 
对其应用一组分区列值的任何现有分区函数的名称。
expression 
其数据类型必须匹配或可隐式转换为其对应分区列数据类型的表达式。expression 也可以是当前参与 partition_function_name 的分区列的名称。
返回类型:
int 
备注:
$PARTITION 返回从 1 到分区函数的分区数之间的 int 值。
$PARTITION 将针对任何有效值返回分区号,无论此值当前是否存在于使用分区函数的分区表或索引中。

我们来查询分区表Order的第一个分区,代码如下:

SQL Server 2008 分区函数和分区表 - 2

可以看到我们查询出来的数据全部为2002年的,也就是说在第一分区中我们存入的数据都是小于2003年,按照此推断2003年的数据,就应该存在第二分区中:

SQL Server 2008 分区函数和分区表 - 3

结果如我们所料,我们可以按照这个分区进行分组来查看各个分区的数据行多少,代码如下:

 

1 select $partition.pf_OrderDate(OrderDate) as Patition,COUNT(*) countRow from dbo.Orders
2 group by $partition.pf_OrderDate(OrderDate)

 

还可以通过$Partition函数获得一组分区标识列值的分区号,例如获得2002属于哪个分区,代码如下:

SQL Server 2008 分区函数和分区表 - 4

2、归档数据

假如现在是2003年年初,那么我们就可以把2002您所有的交易记录归档到我们刚才建立的历史订单表HistroryOrder中。代码如下:

 

1 Use Sales
2 go
3 alter table orders switch partition 1 to ordersHistory partition 1
4 go

 

现在我们再重新查看这两张表的数据:

SQL Server 2008 分区函数和分区表 - 5

这时候Orders表只剩下2003年的数据,而OdersHistory表中包含了2002年的数据。

简单点讲就是把第一区的数据导入到另一张分区表的第一区中。

当然如果到了2004年年初,我们就可以归档2003年的所有交易数据。

 

1 Use Sales
2 go
3 alter table orders switch partition 2 to ordersHistory partition 2
4 go

 

这里需要注意的是我们按照区进行数据修改的时候,必须是同一种分区函数下的分区表进行操作,并且分区结构相对应,如果不这样会报错,例如:

SQL Server 2008 分区函数和分区表 - 6

3、添加分区

当我们需要新添加分区的时候,我们需要修改分区方案,比如现在我们到了2005年年初,我们需要为2005年的交易记录准备分区,就需要添加分区:

 

1 USE [master]
2 GO
3 ALTER DATABASE [Sales] ADD FILEGROUP [FG4]
4 GO
5 ALTER DATABASE [Sales] ADD FILE ( NAME = N'File4', FILENAME = N'G:\data\FG4\File4.ndf' , SIZE = 3072KB , FILEGROWTH = 1024KB ) TO FILEGROUP [FG4]
6 GO

 

我们新建立了一个文件组,然我们同样按照上面的方法,进行修改分区函数和方案:

 

1 use Sales
2 go
3 alter partition scheme ps_OrderDate next used [FG4]
4 alter partition function pf_OrderDate() split range('2005/01/01')
5 go

 

我们这里用alter partition Scheme ps_OrderDate Next Used FG4用来指定新分区的数据在那个文件。这里Next Used FG4指定的就是我们刚才新建立的第四个文件组。当然我们可以放在原来已经建立的文件组,为了防治数据混乱存放我们大部分是新建立文件组。

alter partition function pf_OrderDate() split range('2005/01/01')代表我么创建一个新分区,而这里split range是创建新分区的关键语法。

至此,我们就有了四个分区,此时的区间如下:

文件组 分区 取值范围
FG1 1 (过去某年, 2003/01/01)
FG2 2 [2003/01/01, 2004/01/01)
FG3 3 [2004/01/01,2005/01/01]
FG4 4 [2004/01/01,未来某年)

4、删除分区

删除分区又称合并分区,简单讲就是两个分区的数据进行合并,比如我们想合并2002年的分区和2003年的分区到一个分区,我们可以用如下的代码:

 

1 use Sales
2 go
3 alter partition function pf_OrderDate() merge range('2003/01/01')
4 go

 

也就是将2003年这个分区点去掉,里面分区里面的数据会自动合并到一起。

执行完上面的代码,此时分区区间如下:

文件组 分区 取值范围
Fg2 1 [过去某年, 2004/01/01)
Fg3 2 [2004/01/01, 2005/01/01)
Fg2 3 [2005/01/01, 未来某年)

合并2002和2003年的数据到2003年之后,我们执行如下代码:

 

1 SELECT Sales.$PARTITION.pf_OrderDate('2003')

 

你会发现返回的结果是1。而原来返回的是2,原因是2002年以前数据所在的那个分区合并到了2003年这个分区中了。

此时我们执行下面代码:

 

1 SELECT *
2 FROM dbo.OrdersHistory
3 WHERE $PARTITION.pf_OrderDate(OrderDate) = 2

 

结果一行数据都没返回,事实就这样,因为OrderHistroy表中只存储了2002和2003年的历史数据,在没有合并分区之前,执行上面的代码肯定会查询出2003年的数据,但是合并了分区之后,上面代码实际查询的是第二个分区中2004年的数据。

不过我们改成如下代码:

 

1 SELECT *
2 FROM dbo.OrdersHistory
3 WHERE $PARTITION.pf_OrderDate(OrderDate) = 1

 

便会查询出8行数据,包括2002年和2003年的数据,因为合并分区后2002年和2003年的数据都成了第1分区的数据了。

5、查看元数据

我们可以通过三个系统视图来查看我们的分区函数,分区方案,边界值点等。

 

1 select * from sys.partition_functions
2 select * from sys.partition_range_values
3 select * from sys.partition_schemes
分享到:
评论

相关推荐

    Microsoft SQL Server 2008技术内幕:T-SQL查询(第二卷)

    主要内容包括SQL的基础理论、查询优化、查询算法及复杂度,以及在使用子查询、表表达式、排名函数、数据聚合和透视转换、TOP和APPLY、数据修改、分区表、特殊数据结构等实际应用时会遇到的各种高级查询问题和解决...

    SQLServer2008技术内幕T-SQL查询包含源代码及附录A

    主要内容包括SQL的基础理论、查询优化、查询算法及复杂度,以及在使用子查询、表表达式、排名函数、数据聚合和透视转换、TOP和APPLY、数据修改、分区表、特殊数据结构等实际应用时会遇到的各种高级查询问题和解决...

    Microsoft_SQL_Server_2005技术内幕:T-SQL查询.pdf

    本书适合专业数据库开发者、BI开发者、DBA和以SQL Server作为后台数据库的一般应用程序开发者,读者可以通过书中的最佳实践、高级技巧和代码示例来掌握这门复杂的编程语言,以切合实际的方案来解决复杂的实际问题。...

    Microsoft+SQL+Server+2008技术内幕:T-SQL查询_源代码及附录 中文版

    主要内容包括SQL的基础理论、查询优化、查询算法及复杂度,以及在使用子查询、表表达式、排名函数、数据聚合和透视转换、TOP和APPLY、数据修改、分区表、特殊数据结构等实际应用时会遇到的各种高级查询问题和解决...

    PostgreSQL分区表(partitioning)应用实例详解

    项目中有需求要垂直分表,即按照时间区间将数据拆分到n个表中,PostgreSQL提供了分区表的功能。分区表实际上是把逻辑上的一个大表分割成物理上的几小块,提供了很多好处,比如: 1、查询性能大幅提升 2、删除历史...

    MySQL分区表的局限和限制详解

    禁止构建 分区表达式不支持以下几种构建: 存储过程,存储函数,UDFS或者...在MySQL 5.7.1之前的分区表不支持HANDLER语句,以后的版本取消了这一限制。 服务器SQL模式 如果要用用户自定义分区的表的话,需要注意的是

    大牛出手Oracle SQL优化实例讲解

    1.Oracle如何得到一个很大的表 2.loop insert 实例 3.autotrace验证索引的性能到底有多大? 4.EXPLAIN验证SQL是否走索引 5.结合autotrace创建并验证函数索引 ...18.分区表管理实例,以及常见的错误

    收获不止SQL优化

    7.3.1 分区表相关案例 185 7.3.2 全局临时表案例 190 7.3.3 监控异常的表设计 195 7.3.4 表设计优化相关案例总结 199 7.4 本章习题、总结与延伸 199 第8章 且慢,学习索引如何让SQL飞 200 8.1 索引知识要点...

    收获,不止SQL优化--抓住SQL的本质

    7.3.1 分区表相关案例 185 7.3.2 全局临时表案例 190 7.3.3 监控异常的表设计 195 7.3.4 表设计优化相关案例总结 199 7.4 本章习题、总结与延伸 199 第8章 且慢,学习索引如何让SQL飞 200 8.1 索引知识要点...

    大数据精选入门指南,包括大数据学习路线、大数据技术栈思维导图

    Hive 分区表和分区表 Hive 视图和索引 Hive 使用 DML 操作 Hive数据详细查询解 三、火花 火花核心: 斯帕克简介 Spark开发环境搭建 弹性式数据集 RDD RDD使用算子详解 Spark运行模式与作业提交 Spark 累加器与广播...

    Oracl技术资料(EBook)

    13.PL_SQL单行函数和组函数详解 14.PL-SQL 15.PLSQL异常处理初步 16.SQL语句性能调整原则 17.创建和使用分区的表 18.基于成本的优化器一般错误概念和问题 19.Delphi 3_0中连接数据库的三种方式 20.远程...

    非常全的oracle文档

    24.2. 创建分区表 161 24.3. 范围分区(Range) 161 24.4. 列表分区(List) 164 24.5. 散列分区(Hash) 165 24.6. 组合范围散列分区 167 24.7. 复合范围散列分区 168 24.8. 维护表分区 169 二十四、 PL/SQL基础 173 ...

    Oracle数据库学习指南

    13.PL_SQL单行函数和组函数详解 14.PL-SQL 15.PLSQL异常处理初步 16.SQL语句性能调整原则 17.创建和使用分区的表 18.基于成本的优化器一般错误概念和问题 19.Delphi 3_0中连接数据库的三种方式 20....

    oracle数据库详解PPT

    该压缩包内包括:Oracle函数大全 .ppt Oracle基本体系结构.ppt oracle命令使用大全.doc oracle数据库安装.ppt ... 锁和表分区.ppt 涉及到oracle数据库的方方面面,实在是不可多得的oracle黄金资料

    【63课时完整版】大数据实践HIVE详解及实战

    14.Hive中分区表的创建及使用 15.Hive中数据导入的6种方式及其应用场景 16.Hive中数据导出的4种方式及表的导入导出 17.Hive中HQL的基本语法(一) 18.Hive中HQL的基本语法(二) 19.Hive中order by、sort by、...

Global site tag (gtag.js) - Google Analytics