SQL Server On Linux(23)—— SQL Server On Linux性能(9)——性能进阶简介——分区(3)

本人新书上市,请多多关照: 《SQL Server On Linux运维实战 2017版从入门到精通》

  1. 分区方案是把分区函数映射到物理文件组的过程。
  2. 可以使用ALL关键字把所有分区映射到一个文件组中。
  3. 可以使用Primary关键字把分区映射到数据库的主文件组中。
  4. 修改分区方案意味着指定哪个文件组为NEXT USED。
  5. 使用SPLIT和MERGE管理分区的文件组时,要注意哪些文件组受到影响。
  6. 对于PaaS(SQL Azure)而言,分区方案只能使用Primary文件组。

分区方案

创建分区方案

本文的内容对于Linux上的SQL Server是通用的。因为文件组还是一个逻辑概念,底层的文件比如.mdf/.ndf/.ldf才是物理文件,才是需要考虑Windows/Linux和PaaS环境下的不同,所以你可以看到这里没有出现文件路径的信息。

当配置好分区函数之后,接下来就是分区方案的配置,分区方案(Partition scheme,注意是scheme不是schema)是把分区映射到具体的文件组上,至于文件组里面有多少个文件,则不是它关心的内容,不过不管是否做了分区,当需要大容量载入的时候,多个文件分布在不同的物理驱动器上时,性能通常会比单文件更好。这也是为什么常规建议是使用多个数据文件(注意日志文件并没性能方面的提升)来提高并行读写。

下面是创建分区方案并绑定对应分区函数(PF_RIGHT)的例子,它使用两个文件组来映射。

CREATE PARTITION SCHEME PS_RIGHT AS PARTITION PF_RIGHT TO (FileGroup1, FileGroup2);

技术上并没有强制文件组一定要与分区函数中的边界值一一对应,不过在理想情况下,单一文件组对应一个分区是最好的。如果为了省事或者对于SQL Azure这类PaaS平台,可以使用ALL关键字来把分区放到单一文件组或者使用PRIMARY关键字把所有分区放到数据库的主文件组中。

比如:

CREATE PARTITION SCHEME PS_HASH_BY_VALUE 
AS PARTITION PF_HASH_BY_VALUE
ALL TO ([PRIMARY]);
GO

-- Show the scheme
SELECT * FROM sys.partition_schemes
GO

修改分区方案

和分区函数对比,分区方案的可调整性不强,你可以修改的就是指定哪个文件组会被用于下一个分区,比如把FileGroup5作为下一个分区对应的文件组,可以这样:

ALTER PARTITION SCHEME PS_RIGHT NEXT USED FileGroup5;

如果你预先指定了非常多的文件组,然后后来你不想用它们了,可以删除这些文件组(分区层面上),只需要不指定文件组名即可:

ALTER PARTITION SCHEME PS_RIGHT NEXT USED;

使用ALTER PARTITION FUNCTION拆出来的新分区会映射到标志为NEXT USED的文件组上。

SPLIT/MERGE

分区方案也有SPLIT关键字,当分区函数使用SPLIT或者MERGE来添加或删除边界值时,SQL Server自动调整分区方案中的文件组。但是前提需要有一个文件组被标记为NEXT USED。

比如上面的把FileGroup5设为NEXT USED,那么后续的新分区都会全部落到FileGroup5中。所以在这种场景下,我们首先需要了解到底哪个文件组被标记为NEXT USED。

Merge的行为也是类似的,会把分区合并到其他文件组中,处于性能考虑,在MERGE时,应该指定合并到邻近的文件组中。

管理文件组

基于文件组备份和还原的考虑,通常会建议使用多个文件组来支持分区(SQL Azure只使用Primary)。当使用多文件组时,每个文件组最少要有一个数据文件,并且每个文件组对应一个分区。如果要提升性能,对于本地版的SQL Server,可以把文件组分布在物理驱动器上。

SPLIT选项假设已经有一些文件组被设为NEXT USED,在MERGE的时候,文件组也会被清理,所以在SPLIT和MERGE的时候,要注意并跟踪哪些分区受到了影响。这是其中一个使用分区功能带来的“坏处”,加大了运维的工作量。下面的一些脚本可以用来帮助你了解当前分区情况:

SELECT 
	OBJECT_NAME(SI.object_id) AS PartitionedTable
	, DS.name AS PartitionScheme
	, PF.name AS PartitionFunction
	, P.partition_number
	, P.rows
FROM sys.partitions AS P
JOIN sys.indexes AS SI
	ON P.object_id = SI.object_id AND P.index_id = SI.index_id 
JOIN sys.data_spaces AS DS
	ON DS.data_space_id = SI.

data_space_id

JOIN sys.partition_schemes AS PS

ON PS.data_space_id = SI.data_space_id

JOIN sys.partition_functions AS PF

ON PF.function_id = PS.function_id

WHERE DS.type = ‘PS’

AND OBJECTPROPERTYEX(SI.object_id, ‘BaseType’) = ‘U’

AND SI.type IN(0,1);

SELECT

OBJECT_NAME(SI.object_id) AS PartitionedTable

, DS.name AS PartitionScheme

, PF.name AS PartitionFunction

FROM sys.indexes AS SI

JOIN sys.data_spaces AS DS

ON DS.data_space_id = SI.data_space_id

JOIN sys.partition_schemes AS PS

ON PS.data_space_id = SI.data_space_id

JOIN sys.partition_functions AS PF

ON PF.function_id = PS.function_id

WHERE DS.type = ‘PS’

AND OBJECTPROPERTYEX(SI.object_id, ‘BaseType’) = ‘U’

AND SI.index_id IN(0,1);

SELECT

OBJECT_NAME(SI.object_id) AS PartitionedTable

, DS.name AS PartitionScheme

FROM sys.indexes AS SI

JOIN sys.data_spaces AS DS

ON DS.data_space_id = SI.data_space_id

WHERE DS.type = ‘PS’

AND OBJECTPROPERTYEX(SI.object_id, ‘BaseType’) = ‘U’

AND SI.index_id IN(0,1);

前面提到的主要是针对本地版的SQL Server,当使用云数据库(SQL Azure)时,有一些小细节会有所不一样。这里简单列一下以便读者在后续使用时引起注意:

  1. 最重要的是在云环境下我们只能使用Primary文件组。
  2. SPLIT RANGE函数用来完成NEXT USED时分区号的计算。

后面我会在Azure上做一个完整的演示,这里先介绍基础信息。

我来评几句
登录后评论

已发表评论数()

相关站点

热门文章