当一个表数据量很大时候,很天然咱们就会想到将表拆分红不少小表,在执行查询时候就到各个小表去查,最后汇总数据集返回给调用者加快查询速度。好比电商平台订单表,库存表,因为终年累月读写较多,积累数据都是异常庞大的,这时候,咱们能够想到表分区这个作法,下降运维和维护成本,提升读写性能。好比将前半年订单放一个历史分区表,不活跃库存放一个历史分区表。截止到SQL Server 2016,一张表或一个索引最多能够有15000个分区。数据库
分区范围是指在要分区的表中,根据业务选择表中的关键字段作为分区边界条件,分区后,数据所在的具体位置相当重要,这样才能在须要时只访问相应的分区。注意分区是指数据的逻辑分离,不是数据在磁盘上的物理位置,数据的位置由文件组来决定,因此通常建议一个分区对应一个文件组。运维
分区表中的字段能够做为分区键,好比库存表中供应商ID。对表和索引进行分区的第一步就是定义分区的关键数据。函数
除了对表的数据集进行分区以外,还能够对索引进行分区,使用相同的函数对表及其索引进行分区一般能够优化性能。性能
在这里演示示例当中,我根据业务场景在TestDB数据库新增三个文件组,而三个文件组分别对应三个分区。而多个文件组好处是能够按照不一样业务场景将数据放在对应文件组当中,优化性能同时好维护数据。文件组数量由硬件决定,最好是一个文件组对应一个分区,好维护。而一般文件组都处于不一样磁盘上的,可是因为是演示,我只在一个磁盘中存放。测试
--建立四个文件组
ALTER DATABASE [TestDB] ADD FILEGROUP SupIDGroup1
ALTER DATABASE [TestDB] ADD FILEGROUP SupIDGroup2
ALTER DATABASE [TestDB] ADD FILEGROUP SupIDGroup3
在建立文件组以后,指定文件组存放磁盘位置,文件大小。优化
--建立四个ndf文件,对应到各文件组中,FILENAME文件存储路径 ALTER DATABASE [TestDB] ADD FILE( NAME='SupIDGroupFile1', FILENAME='D:\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\SupIDGroupFile1.ndf', SIZE=10MB, FILEGROWTH=10MB) TO FILEGROUP SupIDGroup1 ALTER DATABASE [TestDB] ADD FILE( NAME='SupIDGroupFile2', FILENAME='D:\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\SupIDGroupFile2.ndf', SIZE=10MB, FILEGROWTH=10MB) TO FILEGROUP SupIDGroup2 ALTER DATABASE [TestDB] ADD FILE( NAME='SupIDGroupFile3', FILENAME='D:\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\SupIDGroupFile3.ndf', SIZE=10MB, FILEGROWTH=10MB) TO FILEGROUP SupIDGroup3
注(附上删除文件组T-SQL):spa
ALTER DATABASE [TestDB] REMOVE FILE SupIDGroupFile3
能够经过如下T-SQL语句查看文件组存放相关信息:3d
SELECT file_id,type,type_desc,data_space_id,name,physical_name,state_desc,size,growth
FROM sys.database_files
如何建立表分区边界值,咱们确定要根据业务场景来决定。好比我测试库库存表有36万左右数据,而有些供应商的库存数据远远比其余供应商大,那么我能够考虑使用供应商ID字段做为边界值分区。例如:根据T-SQL统计,18080供应商库存数据最大,那么我能够根据18080供应商上下分为三个区。
第一个分区范围记录:供应商ID小于等于13570的39097条库存数据。
第二个分区范围记录:供应商ID大于13570和小于等于18079的45962条库存数据。
第三个分区范围记录:供应商ID大于18079小于等于18080的164937条库存数据。
第四个分区范围记录:供应商ID大于18080的111116条库存数据。
根据上述分区范围记录,咱们能够将供应商ID做为边界值设置,执行如下T-SQL语句设置边界值:code
--设置边界值 CREATE PARTITION FUNCTION PF_SupplierID(int) AS RANGE LEFT FOR VALUES (13570,18079,18080)
执行完毕后如图所示:对象
执行如下T-SQL语句建立分区方案:
--建立分区方案
CREATE PARTITION SCHEME PS_SupplierID
AS PARTITION PF_SupplierID TO ([PRIMARY], [SupIDGroup1],[SupIDGroup2],[SupIDGroup3])
执行完毕后如图所示:
上面那些分区步骤都是为了接下来建立分区表这一步骤而准备的。废话很少说,如今咱们来看看如何建立分区表。右键须要分区的表->储存->建立分区,具体步骤以下图所示:
--建立分区索引 CREATE NONCLUSTERED INDEX [NCI_SupplierID] ON dbo.Stock ( SupplierID ASC ) INCLUDE ( [Model],[Brand],[Encapsulation]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) GO
或者
执行完毕后如图所示:
建立好索引以后,咱们来看看分区状况:
--查看各分区有多少行数据 SELECT * FROM ( SELECT $PARTITION.PF_SupplierID([SupplierID]) AS Patition,COUNT(*) AS CountRows FROM dbo.Stock GROUP BY $PARTITION.PF_SupplierID([SupplierID]) )TB ORDER BY Patition
最后咱们来看看加了索引以后表数据查询状况:
优势:
●改善查询性能:对分区对象的查询能够仅搜索本身关心的分区,提升检索速度。
●加强可用性:若是表的某个分区出现故障,表在其余分区的数据仍然可用。
●维护方便:若是表的某个分区出现故障,须要修复数据,只修复该分区便可。
●均衡I/O:能够把不一样的分区映射到不一样磁盘以平衡I/O,改善整个系统性能。
缺点:分区表相关:已经存在的表没有方法能够直接转化为分区表。