SQLSERVER 的表分区(水平) 操作记录2
1 ----(非原创只是自己整理记录!!!)---------------原文地址: https://www.cnblogs.com/libingql/category/184251.html
1.当然需要许多测试数据可以使用 进行生成测试数据 比如我就是10000000万的数据进行操作的
1.适用于已有数据表在进行分区操作的 当然下文有讲到
-- 根据 指定表名 查询 表的约束
exec sp_helpconstraint UserInfo -- UserInfo 表名 -- 根据指定主键约束名删除指定表的主键约束
alter table UserInfo drop constraint PK_UserInfo -- 添加主键约束,但设置为非聚集索引
alter table UserInfo add constraint PK_UserInfo primary key nonclustered (Id) -- 添加一个聚集索引,并使用分区方案指定分区的列 create clustered index CLU_StuNo -- 索引名称
on UserInfo(Id) -- 指定添加索引的表(添加索引的列)
on info_pms(Id) -- 分区方案名称(分区依据的列) --查询的所有的分区函数 名称
SELECT * FROM sys.partition_functions --1.查看分区依据列的指定值所在的分区
----查询分区依据列为10000014的数据在哪个分区上
----返回值是2,表示此值存在第2个分区
select $partition.info_spm(500001) --2.查看分区表中,每个非空分区存在的行数
----查看分区表中,每个非空分区存在的行数 select $partition.row_sp(Id) as partitionNum,count(*) as recordCount
from UserInfo2
group by $partition.row_sp(Id) --得到 表分区下的数据
SELECT * FROM UserInfo WHERE $PARTITION.info_spm(Id) = 1 SELECT * FROM UserInfo WHERE $PARTITION.info_spm(Id) = 2 create CLUSTERED --创建聚集索引 全表唯一
--create clustered index [索引名称] ON 表名称(字段);
--create clustered
--创建非聚集索引 可以不唯一
--create nonclustered index [索引名称] ON 表名称(字段);
--create nonclustered
分区表在逻辑上是一个表,而物理上是多个表。从用户角度来看,分区表和普通表是一样的。使用分区表的主要目的是为改善大型表以及具有多个访问模式的表的可伸缩性和可管理性。
分区表是把数据按设定的标准划分成区域存储在不同的文件组中,使用分区可以快速而有效管理和访问数据子集。
1.1> 适合做分区表的情况
◊ 数据库中某个表的数据很多,在查询数据时会明显感觉到速度很慢,这个时候需要考虑分区表;
◊ 数据是分段的,如以年份为分隔的数据,对于当年的数据经常进行增删改查操作,而对于往年的数据几乎不做操作或只做查询操作,这种情况可以使用分区表。对数据的操作如果只涉及一部分数据而不是全部数据的情况可以考虑分区表,如果一张表的数据经常使用且不管年份之类的因素经常对其增删改查操作则最好不要分区。
1.2> 分区表的优点
◊ 分区表可以从物理上将一个大表分成几个小表,但是从逻辑上来看还是一个大表。
◊ 对于具有多个CPU的系统,分区可以对表的操作通过并行的方式进行,可以提升访问性能。
2. 创建分区表步骤
创建分区表的步骤分为5步:
(1)创建数据库文件组
(2)创建数据库文件
(3)创建分区函数
(4)创建分区方案
(5)创建分区表
2.1> 创建数据库文件组
新建示例数据库Northwind,创建数据库文件组和文件,添加文件组。
2.2> 创建数据库文件
创建数据文件,并为数据文件分配文件组。
完成创建后的数据库文件信息
通过SQL Server Profiler可以看到具体的创建数据库的脚本如下:
CREATE DATABASE [Northwind]
CONTAINMENT = NONE
ON PRIMARY
( NAME = N'Northwind', FILENAME = N'F:\Database\Northwind\Northwind.mdf' , SIZE = 5120KB , FILEGROWTH = 1024KB ),
FILEGROUP [SECTION2010]
( NAME = N'Northwind_Data_2010', FILENAME = N'F:\Database\Northwind\Northwind_Data_2010.ndf' , SIZE = 5120KB , FILEGROWTH = 1024KB ),
FILEGROUP [SECTION2011]
( NAME = N'Northwind_Data_2011', FILENAME = N'F:\Database\Northwind\Northwind_Data_2011.ndf' , SIZE = 5120KB , FILEGROWTH = 1024KB ),
FILEGROUP [SECTION2012]
( NAME = N'Northwind_Data_2012', FILENAME = N'F:\Database\Northwind\Northwind_Data_2012.ndf' , SIZE = 5120KB , FILEGROWTH = 1024KB ),
FILEGROUP [SECTION2013]
( NAME = N'Northwind_Data_2013', FILENAME = N'F:\Database\Northwind\Northwind_Data_2013.ndf' , SIZE = 5120KB , FILEGROWTH = 1024KB ),
FILEGROUP [SECTION2014]
( NAME = N'Northwind_Data_2014', FILENAME = N'F:\Database\Northwind\Northwind_Data_2014.ndf' , SIZE = 5120KB , FILEGROWTH = 1024KB )
LOG ON
( NAME = N'Northwind_log', FILENAME = N'F:\Database\Northwind\Northwind_log.ldf' , SIZE = 2048KB , FILEGROWTH = 10%)
查看数据库文件组SQL语句:
2.3> 创建分区函数
创建分区函数Transact-SQL语法:
CREATE PARTITION FUNCTION partition_function_name ( input_parameter_type )
AS RANGE [ LEFT | RIGHT ]
FOR VALUES ( [ boundary_value [ ,...n ] ] )
[ ; ]
参数:
partition_function_name:分区函数的名称。 分区函数名称在数据库内必须唯一,并且符合标识符的规则。
input_parameter_type:用于分区的列的数据类型。 当用作分区列时,除 text、ntext、image、xml、timestamp、varchar(max)、nvarchar(max)、varbinary(max)、别名数据类型或 CLR 用户定义数据类型外,所有数据类型均有效。
boundary_value:为使用 partition_function_name 的已分区表或索引的每个分区指定边界值。 如果 boundary_value 为空,则分区函数使 partition_function_name 将整个表或索引映射到单个分区。 只能使用 CREATE TABLE 或 CREATE INDEX 语句中指定的一个分区列。
LEFT | RIGHT 指定当间隔值由 数据库引擎 按升序从左到右排序时,boundary_value [ ,...n ] 属于每个边界值间隔的哪一侧(左侧还是右侧)。 如果未指定,则默认值为 LEFT。
示例:创建将用于Order表的分区函数
CREATE PARTITION FUNCTION Function_DateTime ( DATETIME )
AS RANGE RIGHT
FOR VALUES('2011-01-01', '2012-01-01', '2013-01-01', '2014-01-01')
完成创建分区函数之后,可以通过以下SQL语句查看已创建的分区函数情况。
SELECT * FROM sys.partition_functions
2.4> 创建分区方案
分区方案的作用是将分区函数生成的分区映射到文件组中去,分区方案是让SQL Server将已分区的数据放在哪个文件组中。
在当前数据库中创建一个将已分区表或已分区索引的分区映射到文件组的方案。 已分区表或已分区索引的分区的个数和域在分区函数中确定。 必须首先在 CREATE PARTITION FUNCTION 语句中创建分区函数,然后才能创建分区方案。
创建分区方案的Transact-SQL语法:
CREATE PARTITION SCHEME partition_scheme_name
AS PARTITION partition_function_name
[ ALL ] TO ( { file_group_name | [ PRIMARY ] } [ ,...n ] )
[ ; ]
参数:
partition_scheme_name:分区方案的名称。 分区方案名称在数据库中必须是唯一的,并且符合标识符规则。
partition_function_name:使用分区方案的分区函数的名称。 分区函数所创建的分区将映射到在分区方案中指定的文件组。 partition_function_name 必须已经存在于数据库中。 单个分区不能同时包含 FILESTREAM 和非 FILESTREAM 文件组。
ALL:指定所有分区都映射到在 file_group_name 中提供的文件组,或映射到主文件组(如果指定了 [PRIMARY]。 如果指定了 ALL,则只能指定一个 file_group_name。
file_group_name | [ PRIMARY ] [ ,...n]:指定用来持有由 partition_function_name 指定的分区的文件组的名称。 file_group_name 必须已经存在于数据库中。
如果指定了 [PRIMARY],则分区将存储于主文件组中。 如果指定了 ALL,则只能指定一个 file_group_name。 分区分配到文件组的顺序是从分区 1 开始,按文件组在 [,...n] 中列出的顺序进行分配。 在 [,...n] 中,可以多次指定同一个 file_group_name。 如果 n 不足以拥有在 partition_function_name 中指定的分区数,则 CREATE PARTITION SCHEME 将失败,并返回错误。
如果 partition_function_name 生成的分区数少于文件组数,则第一个未分配的文件组将标记为 NEXT USED,并且出现显示命名 NEXT USED 文件组的信息。 如果指定了 ALL,则单独的 file_group_name 将为该 partition_function_name 保持它的 NEXT USED 属性。 如果在 ALTER PARTITION FUNCTION 语句中创建了一个分区,则 NEXT USED 文件组将再接收一个分区。 若要再创建一个未分配的文件组来拥有新的分区,请使用 ALTER PARTITION SCHEME。
在 file_group_name[ 1,...n] 中指定主文件组时,必须像在 [PRIMARY] 中那样分隔 PRIMARY,因为它是关键字。
示例:创建将用于Order表的分区方案
CREATE PARTITION SCHEME Scheme_DateTime
AS PARTITION Function_DateTime
TO ( SECTION2010, SECTION2011, SECTION2012, SECTION2013, SECTION2014 )
分区函数和分区方案创建之后,可以在数据库的【存储】中查看:
通过可以通过以下SQL语句查看已创建的分区方案:
SELECT * FROM sys.partition_schemes
2.5> 创建分区表
CREATE TABLE [Order]
(
OrderID INT IDENTITY(1,1) NOT NULL,
UserID INT NOT NULL,
TotalAmount DECIMAL(18,2) NULL,
OrderDate DATETIME NOT NULL
) ON Scheme_DateTime ( OrderDate )
这里需要注意分区表不能再创建聚集索引,因为聚集索引可以将记录在物理上顺序存储,而分区表是将数据存储在不同的表中,这两个概念是冲突的,所以在创建分区表时不能再创建聚集索引。
完成Order表创建之后,查看表的属性,可以看到Order表已经是分区表。
3. 操作分区表
3.1> Insert数据
USE [Northwind]
GO INSERT INTO [dbo].[Order] ([UserID],[TotalAmount] ,[OrderDate]) VALUES (1 ,10.00 ,'2009-10-20');
INSERT INTO [dbo].[Order] ([UserID],[TotalAmount] ,[OrderDate]) VALUES (1 ,20.50 ,'2009-12-31');
INSERT INTO [dbo].[Order] ([UserID],[TotalAmount] ,[OrderDate]) VALUES (2 ,40.00 ,'2010-01-20');
INSERT INTO [dbo].[Order] ([UserID],[TotalAmount] ,[OrderDate]) VALUES (3 ,40.00 ,'2010-10-20');
INSERT INTO [dbo].[Order] ([UserID],[TotalAmount] ,[OrderDate]) VALUES (4 ,50.00 ,'2011-10-20');
INSERT INTO [dbo].[Order] ([UserID],[TotalAmount] ,[OrderDate]) VALUES (5 ,60.00 ,'2012-10-20');
INSERT INTO [dbo].[Order] ([UserID],[TotalAmount] ,[OrderDate]) VALUES (5 ,60.00 ,'2012-10-20');
INSERT INTO [dbo].[Order] ([UserID],[TotalAmount] ,[OrderDate]) VALUES (6 ,70.00 ,'2013-10-20');
INSERT INTO [dbo].[Order] ([UserID],[TotalAmount] ,[OrderDate]) VALUES (10 ,90.00 ,'2014-10-20');
INSERT INTO [dbo].[Order] ([UserID],[TotalAmount] ,[OrderDate]) VALUES (9 ,100.00 ,'2015-10-20');
GO
3.2> 查询数据所在物理分区表
在分区表中使用一般的SELECT语句无法知道数据是分别存放在哪几个不同的物理表中,若要知道数据分别存放的物理表,可以使用$PARTITION函数,该函数可以调用分区函数并返回数据所在物理分区的编号。
$PARTITION的语法:$PARTITION.分区函数名(表达式)
SELECT $PARTITION.Function_DateTime('2010-01-01')
查询结果分区函数返回为1,说明2010-01-01的数据会存放在第1个物理分区表中。
使用$PARTITION函数可以具体知道每个物理分区表中存放了哪些记录。
查看物理分区表中存放的记录:
SELECT * FROM [Order] WHERE $PARTITION.Function_DateTime(OrderDate) = 1
SELECT $PARTITION.Function_DateTime(OrderDate) AS 分区编号, COUNT(1) AS 记录数
FROM [Order]
GROUP BY $PARTITION.Function_DateTime(OrderDate)
3.3> 修改分区表数据
UPDATE dbo.[Order] SET OrderDate='2015-01-01' WHERE OrderID = 3
4. 将普通表转换为分区表
一般的普通表都是在主键上建聚集索引,记录的物理保存位置由主键决定。
示例:创建一个Product普通表
CREATE TABLE Product
(
ProductID INT IDENTITY(1,1) NOT NULL,
ProductName VARCHAR(100) NOT NULL,
UnitPrice DECIMAL(18,2) NULL,
CreateDate DATETIME NOT NULL,
CONSTRAINT PK_Product PRIMARY KEY CLUSTERED (ProductID)
)
USE [Northwind]
GO INSERT INTO [dbo].[Product] ([ProductName],[UnitPrice],[CreateDate]) VALUES ('LINQ to SQL' ,10 ,'2012-01-01');
INSERT INTO [dbo].[Product] ([ProductName],[UnitPrice],[CreateDate]) VALUES ('LINQ to XML' ,10 ,'2012-12-01');
INSERT INTO [dbo].[Product] ([ProductName],[UnitPrice],[CreateDate]) VALUES ('LINQ to Object' ,10 ,'2013-02-01');
INSERT INTO [dbo].[Product] ([ProductName],[UnitPrice],[CreateDate]) VALUES ('LINQ to ADO.NET' ,10 ,'2014-01-02');
INSERT INTO [dbo].[Product] ([ProductName],[UnitPrice],[CreateDate]) VALUES ('LINQ to Entity' ,10 ,'2015-01-01'); GO
查看表Product的属性:
查看表Product的索引,可以看到PK_Product为聚集索引。
将普通表转换为分区表的操作是先在普通表上删除聚集索引,在创建一个新的聚集索引,在该聚集索引中使用分区方案。
在SQL Server中,主键字段上默认创建聚集索引,删除主键的聚集索引。
ALTER TABLE Product DROP CONSTRAINT PK_Product
重新创建主键非聚集索引
ALTER TABLE Product ADD CONSTRAINT PK_Product PRIMARY KEY NONCLUSTERED (ProductID ASC)
重新创建后的主键:
创建使用分区方案的聚集索引:
CREATE CLUSTERED INDEX IX_CreateDate ON Product ( CreateDate )
ON Scheme_DateTime ( CreateDate )
调整后的Product表属性:
调整后Product表记录的物理保存情况:
5. 删除(合并)一个分区表
删除2012-01-01的分区,修改分区函数:
ALTER PARTITION FUNCTION Function_DateTime() MERGE RANGE ('2012-01-01')
在修改了分区函数之后,与之关联的分区方案也将同时自动调整。在执行了上面合并分区的函数之后,查看分区方案的Create脚本。
CREATE PARTITION SCHEME [Scheme_DateTime] AS PARTITION [Function_DateTime] TO ([SECTION2010], [SECTION2011], [SECTION2013], [SECTION2014])
合并分区之后,被合并的分区记录也将被重新分配物理保存位置。
6. 添加分区
分区方案中指定的文件组个数比分区函数中指定的边界数大1,为分区方案指定一个可用的文件组时,该分区方案并没有立刻使用这个文件组,只是将文件组先备用着,等修改了分区函数之后分区方案才会使用这个文件组。如果分区函数没有更改,分区方案中的文件组个数也不会更改。
添加分区所需要使用到的文件组可以使用之前合并分区之后没有再使用的SECTION2012,也可以新建文件组。
ALTER DATABASE [Northwind] ADD FILEGROUP [SECTION2015]
ALTER DATABASE [Northwind] ADD FILE
(
NAME = N'Northwind_Data_2015',
FILENAME = N'F:\Database\Northwind\Northwind_Data_2015.ndf' ,
SIZE = 5120KB ,
FILEGROWTH = 1024KB
) TO FILEGROUP [SECTION2015]
为分区方案指定一个可用的文件组:
ALTER PARTITION SCHEME Scheme_DateTime NEXT USED [SECTION2015]
修改分区函数,添加分区:
ALTER PARTITION FUNCTION Function_DateTime() SPLIT RANGE('2015-01-01')
查看添加分区后的数据物理存储:
SQLSERVER 的表分区(水平) 操作记录2的更多相关文章
- SQL Server表分区-水平分区
SQL Server表分区,sql server水平分区 转自:http://www.cnblogs.com/knowledgesea/p/3696912.html 根据时间的,直接上T-SQL代码 ...
- hive表分区相关操作
Hive 表分区 Hive表的分区就是一个目录,分区字段不和表的字段重复 创建分区表: create table tb_partition(id string, name string) PARTIT ...
- sqlserver 数据库表分区
参考文档 https://msdn.microsoft.com/zh-cn/library/ms345146(SQL.90).aspx http://blog.sina.com.cn/s/blog_4 ...
- sqlserver 删除表分区
我们都知道,SQL server2008R2企业版以及一些其它的版本支持分区函数,当你在这些数据库备份后想在一些不支持分区函数的数据库做还原时,就会失败. 下面我们来解决这个问题. 1.备份数据库!备 ...
- sqlserver 2008r2 表分区拆分问题
问题描述: 对tab1表实行自动天分区,每天通过sqlserver代理-作业00:00点自动生成分区: 因有次停了数据库服务,sqlserver 代理服务忘记开启,导致当天00:00没有生成新分区: ...
- mongodb安装,库操作,集合操作(表),文档操作(记录)
安装 1.下载地址 https://fastdl.mongodb.org/win32/mongodb-win32-x86_64-2008plus-ssl-4.0.8-signed.msi 2.如果报没 ...
- SqlServer系统表认识和操作
地址:http://technet.microsoft.com/zh-cn/library/ms178551.aspx 一.sys.sysindexkeys 包含有关数据库的索引中的键或列的信息.(表 ...
- 记一次oracle新建用户及分配指定表权限的操作记录
1.登录 2.创建用户create user new用户名 identified by new用户名创建new用户名用户,密码设置为new用户名. 3.授权new用户名用户的连接.资源权限.grant ...
- sqlserver表分区小结
为什么要表分区? 当一个表的数据量太大的时候,我们最想做的一件事是什么?将这个表一分为二或者更多分,但是表还是这个表,只是将其内容存储分开,这样读取就快了N倍了 原理:表数据是无法放在文件中的,但是 ...
- sqlserver2012 表分区
无论是新建数据库,还是现有的问题,都可以执行表分区的操作. 1.在数据库中点鼠标右键点击属性,在选择页,选中文件栏,在数据库文件列表中,可以看到现有的数据库文件逻辑名称.文件类型.初始大小.保存位置等 ...
随机推荐
- Java I/O 教程(一) 介绍
Java I/O (Input and Output) 用于处理输入和输出 Java利用流的手段来加快I/O操作.java.io包中包含了各种支持输入输出操作的类.参考下图: 我们可以利用java i ...
- D. Required Length
D. Required Length 题意:给你一个长度n,一个数x,x每个后续状态可以由前一个状态乘以前一个状态的某一位上的数字得到,问最少多少步,能把x变成一个n位数.如果不能变成n位数,输出-1 ...
- G water testing题解
G water testing 题意:给你一个多边形(可能是凸多边形,也可能是凹多边形),问该多边形内有多少个整数点(不包含边界). 思路:皮克定理 + 叉乘计算三角形面积:皮克定理是指一个计算点阵中 ...
- 项目实战:Qt+Android模拟操作器(模拟操作app,打开,点击,输入,获取验证码等等)
若该文为原创文章,转载请注明原文出处本文章博客地址:https://blog.csdn.net/qq21497936/article/details/109313803各位读者,知识无穷而人力有穷,要 ...
- golang泛型简介
linux下go版本安装(1.18.1版本) >>> wget https://go.dev/dl/go1.18.1.linux-amd64.tar.gz >>> ...
- linux系统优化命令--day03
用户管理与文件权限 给普通用户授权 root 用户 修改/etc/sudoers文件,文件非常重要, 不可以随意更改 vim /etc/sudoers 如果想要给用户赋予权限,我们要使用这个命令 vi ...
- ABP Suite创建新项目
启动Abp Suite ********************************************************************** ** Visual Studio ...
- 【Azure 存储服务】如何查看Storage Account的删除记录,有没有接口可以下载近1天删除的Blob文件信息呢?
问题描述 如何查看Storage Account的删除记录,有没有接口可以下载近1天删除的Blob文件信息呢?因为有时候出现误操作删除了某些Blob文件,想通过查看删除日志来定位被删除的文件信息. 问 ...
- 【Azure 事件中心】China Azure上是否有Kafka服务简答
问题描述 China Azure 上是否有Kakfa服务可以使用呢? 问题回答 China Azure并没有专门的Kafka服务,但是可以使用Azure Event Hub. 创建标准版及以上的Eve ...
- [C++逆向] 8 数组和指针的寻址
目录 数组在函数中 字符串 数组作为参数 下标寻址和指针寻址 多维数组 存放指针类型数据的数组 指向数组的指针变量 函数指针 数组是相同类型数据的集合,以先行方式连续储存在内冲中 而指针只是一个保存地 ...