MSSQL 高效利用分区提升数据处理能力

1.什么是SQL Server分区?

在数据库系统中,分区是一种改进性能的技术。SQL Server分区是一种将表或索引划分为多个物理或逻辑部分的方法,每个部分都可以由SQL Server分别管理。通过采用分区策略,可以提高查询和维护操作的效率,提高系统的可用性和可扩展性。

2.为什么需要分区?

SQL Server分区的主要目的是提高数据库的性能和可管理性,它能够以以下方式提高性能:

2.1 减少数据访问

所谓SQL Server分区,就是将一张大表拆分成若干张小表来存储。这样的好处是极其显然的:当需要查询数据时,可以只访问其中一个小表,而非大表中的所有数据。这就极大地减少了数据访问量,从而提高了性能。

2.2 分布查询

对于分布式数据库,SQL Server分区就是一个非常有用的工具。通过对分区策略的选择,可以让不同的分区部署在不同的节点上。这样在进行查询时,不同的节点可以并行地处理分别部分,从而更加高效。

2.3 数据维护

对于大型的数据库,数据的维护可能是非常耗时的操作。例如在一张大表中进行备份、索引重建等操作需要花费大量的时间和计算资源。而通过使用SQL Server分区,我们可以只对部分数据进行维护操作,这不仅减少了耗时,更重要的是减少了对整个系统的影响。

3.如何分区?

分区策略不只是简单的将一张表在某个特定列的数值进行分组,而且需要考虑查询情况下是如何利用这个分区的。否则将会遇到以下情况:

3.1 没有减少数据访问量

分区后,查询如果是在分区键上,则可以在一个子表内进行查询。否则就必须遍历全部分区。一旦有任何一个分区未命中,则必须扫描所有的数据。

3.2 不良的分区键

选定分区建时需要是进行认真的分析。如果选定不合适的分区建,就会使得查询人员无法进行快速操作或者降低查询速度。

4.分区的类型

共有四种方法可以应用分区策略。从技术上说,这些策略是等价的,因为它们提供相同的特性和功效。只是在某些特定的情况下,使用一种分区策略会更加的恰当。

4.1 Range分区

这种类型是最常用的分区策略。它根据数据的范围将行分布到不同的分区上,分区的取值可以是数字、日期时间或字符。

CREATE PARTITION FUNCTION pf_分区名称(int 或大于零的数字)

AS RANGE LEFT

(

{计算列 | 字面值} [, ...n]

)

//例如,对一个分布式的联系人表,要根据地址列进行分区

CREATE PARTITION FUNCTION pf_Address(int)

AS RANGE LEFT

(

AddressLine1, AddressLine2, City, StateProvinceID, PostalCode

)

4.2 Hash分区

根据一个表达式的哈希值将行分布到不同的分区上。HASH函数确定数据项几乎等可能的分配到各个分区中。

CREATE PARTITION FUNCTION pf_分区名称(int 或大于零的数字)

AS HASH { 小于最大值的计算列 | 参数 | NEWID() }

//例如,在分布式的订单详细表上,可以选定计算列“客户ID”作为哈希计算列

CREATE PARTITION FUNCTION pf_CustomerID(int)

AS HASH(CustomerID)

4.3 List分区

这种类型在分区键的取值上面进行划分也就是说, 每一个区取值是可以指定的。

CREATE PARTITION FUNCTION func_f分区名列表(nvarchar(50))

AS LIST(N'取值1′,

N'取值2′,

……,

N'取值n′)

//例如,在分布式的人员表上,需要将表内容分为“员工”和“岗位”两类,这就可以使用LIST分区方式

CREATE PARTITION FUNCTION pf_Employees nvarchar(50))

AS LIST(N'Emp', N'Mgr')

CREATE PARTITION SCHEME ps_Employees AS PARTITION pf_Employees TO (fg_Employees_1, fg_Employees_2)

4.4 Composite分区

这种类型把上面三种技术进行了组合使用。 例如,在一个跨度很长的日期范围内,可以使用 RANGE 分区策略,再按照 HASH 分区策略运用不同的密钥进行拆分,把最后的行分发到不同的分区里。

CREATE PARTITION FUNCTION pf_Year(int)

AS RANGE LEFT FOR VALUES (…)

CREATE PARTITION FUNCTION pf_Month(int)

AS RANGE LEFT FOR VALUES (…)

CREATE PARTITION SCHEME ps_myScheme

AS PARTITION pf_Year TO ( fg_Y2008, fg_Y2009, fg_Y2010 ),

PARTITION pf_Month TO ( fg_M1, fg_M2, fg_M3, …, fg_M11, fg_M12 )

WHERE the YEAR field is used with a modulus function

to define whether a partition resides on primary or secondary filegroups

and the MONTH field is used with a hash function

to define which of the 12 filegroups in a year partition are used.

5.分区例子

这里通过 RANGE 方式对创建的表进行分区,对 Temperature (温度)的值进行筛选。

-- 创建数据分区函数

CREATE PARTITION FUNCTION pf_temperature ( decimal(10,2) )

AS RANGE LEFT FOR VALUES (0,10,20,30,40,50,60,70,80,90,100);

GO

-- 创建数据分区计划

CREATE PARTITION SCHEME ps_temperature

AS PARTITION pf_temperature ALL TO( [Primary] );

GO

-- 创建分区表

CREATE TABLE Partition_Temperature

(

TemperatureID INT PRIMARY KEY,

City NVARCHAR(50),

Temperature DECIMAL(10,2)

) ON ps_temperature(Temperature);

GO

6.程序化查找分区

这里介绍如何通过程序看分区结果。

CREATE PARTITION SCHEME ps_Temperature

AS PARTITION pf_partition

ALL TO ( [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY] );

CREATE PARTITION FUNCTION pf_partition (int)

AS RANGE LEFT FOR VALUES (10, 50, 100);

ALTER PARTITION SCHEME ps_Temperature

next used [PRIMARY];

SELECT DISTINCT partition_number

FROM sys.partitions WITH(NOLOCK)

WHERE object_id = OBJECT_ID('dbo.Temperature_Data_Storage')

7.分区操作中需要注意的问题

7.1 备份和恢复

当使用 SQL Server分区时,需要在备份和恢复方面进行额外的处理。在备份数据库时,必须对每个分区进行分别备份。而在恢复时,必须将分区放在独立的文件中,以便单独恢复一个或多个分区。

7.2 在使用ROW_NUMBER进行分页查找

当在使用ROW_NUMBER进行分页查找时,必须同时使用分区列,否则查询后将会得到错误的结果。

8.SQL Server分区优缺点

8.1 优点:

提高了查询速度。对于大型表中包含海量数据的情况下,可以将其划分为小型数据集,缩短查询时间。

方便数据库的备份和恢复。可以对每个分区进行独立的备份,缩短备份的时间。同样,在恢复数据库时,可以只恢复出问题的分区,缩短恢复的时间。

可以达到较好的可扩展性。使用SQL Server分区,可以轻松增加或减少分区数量,来适应数据量和访问频率的变化。

8.2 缺点:

尽管分区查询会加快查询速度,但是维护分区也会对数据库的性能造成一定的影响。因为一个分区的变化会影响整个数据库的操作。

需要额外的管理。一个数据库的分区必须得到专业的管理,也就是说额外的工作量和更高的技术津贴。

很难跨分区进行查询,因为跨分区的查询效率较低,只有在必要时才应该使用。

9.总结

SQL Server分区的设计可以显著提高查询速度,提高系统的可用性和可扩展性。在使用SQL Server分区时,必须使用正确的分区策略和分区建,以便更好地提高性能。然而,需要注意的是,分区也会对数据库性能造成一定的影响,管理分区需要额外的工作量。因此,使用SQL Server分区是一个权衡利弊的过程。

数据库标签