1. 程式人生 > 其它 >SqlServer分割槽設定(按時間)

SqlServer分割槽設定(按時間)

分割槽表

通常單表資料量到達百萬級別就需要使用分庫、分割槽、分表操作來達到一個均衡的效果。
新建立的資料表的資料會預設存在資料庫的.mdf檔案裡,而分割槽表資料會按照指定的分割槽方案(Scheme)儲存在不同檔案裡。

優點:

  1. 均衡I/O: 分割槽檔案對映到不同磁碟可以平衡I/O效率,改善系統性能
  2. 增加可用性:單個分割槽出現問題,其餘分割槽正常使用。
  3. 提高檢索速度:按分割槽可避免全表掃描

缺點:

  1. 管理難度提升,需要管理的物件:Group列表、File列表、Scheme、Func、定時任務

以下流程最終效果為:一個表對應一個方案;一個方案對應一個函式對應多個檔案組;一個檔案組對應一個檔案

建立流程:

1)新建分割槽檔案組
2)新建分割槽檔案
3)新建分割槽函式與分割槽方案
4)新建表/繫結現有表

建立分割槽表 (T_sql方式)

1)建立分割槽檔案組

一個檔案組對應一個檔案,那為什麼還需要檔案組這個概念存在?
DBA:檔案組是資料庫一個負載均衡的維度,在這裡體現不出優點來

-- 建立檔案組
ALTER DATABASE [db_hmTest] ADD FILEGROUP db_hmTest_OrderGroup202105;
ALTER DATABASE [db_hmTest] ADD FILEGROUP db_hmTest_OrderGroup202106;
ALTER DATABASE [db_hmTest] ADD FILEGROUP db_hmTest_OrderGroup202107;
ALTER DATABASE [db_hmTest] ADD FILEGROUP db_hmTest_OrderGroup202108;

2)建立檔案

每個資料庫都有個預設的檔案組【PRIMARY】

-- 建立檔案
ALTER DATABASE [db_hmTest] ADD 
FILE(NAME=N'db_hmTest_Order202105',FILENAME=N'D:\DB\Partition\db_hmTest_Order202105.mdf',SIZE=5MB,FILEGROWTH=1MB,MAXSIZE=UNLIMITED)
TO FILEGROUP [db_hmTest_OrderGroup202105]

ALTER DATABASE [db_hmTest] ADD 
FILE(NAME=N'db_hmTest_Order202106',FILENAME=N'D:\DB\Partition\db_hmTest_Order202106.mdf',SIZE=5MB,FILEGROWTH=1MB,MAXSIZE=UNLIMITED)
TO FILEGROUP [db_hmTest_OrderGroup202106]

ALTER DATABASE [db_hmTest] ADD 
FILE(NAME=N'db_hmTest_Order202107',FILENAME=N'D:\DB\Partition\db_hmTest_Order202107.mdf',SIZE=5MB,FILEGROWTH=1MB,MAXSIZE=UNLIMITED)
TO FILEGROUP [db_hmTest_OrderGroup202107]

ALTER DATABASE [db_hmTest] ADD 
FILE(NAME=N'db_hmTest_Order202108',FILENAME=N'D:\DB\Partition\db_hmTest_Order202108.mdf',SIZE=5MB,FILEGROWTH=1MB,MAXSIZE=UNLIMITED)
TO FILEGROUP [db_hmTest_OrderGroup202108]

3)建立分割槽函式與分割槽方案

按照以下設定,效果為:
db_hmTest_OrderGroup202105檔案儲存範圍: (-∞,2021-06-01T00:00:000)
db_hmTest_OrderGroup202106檔案儲存範圍: [2021-06-01T00:00:000,2021-07-01T00:00:000)
db_hmTest_OrderGroup202107檔案儲存範圍: [2021-07-01T00:00:000,2021-08-01T00:00:000)
db_hmTest_OrderGroup202108檔案儲存範圍: [2021-08-01T00:00:000,+∞)

-- 建立分割槽函式
CREATE PARTITION FUNCTION HmTest_Order_Func(DATETIME2(2))
AS RANGE RIGHT FOR 
VALUES(N'2021-06-01T00:00:00.000',N'2021-07-01T00:00:00.000',N'2021-08-01T00:00:00.000')

-- 建立分割槽方案
CREATE PARTITION SCHEME HmTest_Order_Scheme AS PARTITION HmTest_Order_Func
TO([db_hmTest_OrderGroup202105],[db_hmTest_OrderGroup202106],[db_hmTest_OrderGroup202107],[db_hmTest_OrderGroup202108])

4)新建表/繫結現有表

通常情況下id作為表的主鍵,但在這裡是按add_time作為分割槽關聯列的。所以我選的方案是用id+add_time做聯合主鍵-聚合索引

-- 建立表並繫結分割槽方案
IF OBJECT_ID(N'[dbo].[t_order]',N'U') IS NOT NULL
DROP TABLE [t_order];
CREATE TABLE [t_order](
id INT NOT NULL,
product NVARCHAR(200) NOT NULL,
size FLOAT NOT NULL,
add_time DATETIME2(2) NOT NULL
PRIMARY KEY(id,[add_time])
) ON HmTest_Order_Scheme([add_time])


-- 繫結現有表
CREATE CLUSTERED INDEX PK_hmTest_order_id_addTime ON 
[dbo].[t_order_01]([id],[add_time])
WITH(SORT_IN_TEMPDB=OFF,DROP_EXISTING=OFF,ONLINE=OFF) ON 
[HmTest_Order_Scheme]([add_time]);

儲存過程 - 動態分割槽

通常做法是,資料庫會做定時任務,每月第一天執行下面的儲存過程,每月產生一個檔案組和檔案

-- 新建儲存過程,每月新增一個檔案組
CREATE PROCEDURE [Prop_HmOrder_AutoExtend_Partition]
AS
BEGIN
 DECLARE @FilePath VARCHAR(100), --檔案路徑
 @FileName VARCHAR(100), --檔名稱
 @FileSize VARCHAR(100), --檔案大小
 @FileGrowth VARCHAR(100), --檔案增長
 @FileMaxLimit VARCHAR(100), --檔案最大限制
 @FileGroupName VARCHAR(100), --檔案組名稱
 @Database VARCHAR(100), --操作資料庫
 @CurrentDateTimeByYearAndMonth VARCHAR(100), --當前時間,年月
 @SchemeName VARCHAR(100), --分割槽方案名稱
 @PartitionName VARCHAR(100), --分割槽函式名稱
 @sql VARCHAR(400); -- 賦值檔案屬性
 SET @FileSize = '5MB';
 SET @FileGrowth = '1MB';
 SET @FileMaxLimit = 'unlimited';
 SET @CurrentDateTimeByYearAndMonth = LEFT(CONVERT(VARCHAR(30), GETDATE(), 112), 6);
 SET @FileName = 'db_hmTest_Order' + @CurrentDateTimeByYearAndMonth;
 SET @FilePath = 'D:\DB\Partition';
 -- 賦值資料庫屬性
 SET @Database = 'db_hmTest';
 -- 賦值檔案組屬性
 SET @FileGroupName = 'db_hmTest_OrderGroup' + @CurrentDateTimeByYearAndMonth;
 -- 賦值分割槽屬性
 SET @SchemeName = 'HmTest_Order_Scheme';
 SET @PartitionName = 'HmTest_Order_Func()';
 -- 建立檔案組
 SET @sql = 'alter database ' + @Database + ' add filegroup ' + @FileGroupName + '';
 EXEC (@sql);
 -- 建立檔案,並繫結檔案組
 SET @sql = 'alter database ' + @Database + ' add file (name=''' + @FileName + ''',' + 'filename=''' + @FilePath + '\'
 + @FileName + '.mdf'',' + 'size = ' + @FileSize + ',' + 'filegrowth = ' + @FileGrowth + ',' + 'maxsize = '
 + @FileMaxLimit + '' + ')' + 'to filegroup ' + @FileGroupName;
 EXEC (@sql);
 -- 修改分割槽方案
 SET @sql = 'alter partition scheme ' + @SchemeName + ' next used ' + 
@FileGroupName + '';
 EXEC (@sql);
 -- 修改分割槽函式
 SET @sql = 'alter partition function ' + @PartitionName + ' split range (N''' +CONVERT(varchar(30), GETDATE(), 120) +''')'
 EXEC (@sql);
END;
GO

雜項列表

1)db_hmTest_OrderGroup202108會包含[2021-08-01T00:00:000,+∞)。後期動態新增檔案組時,資料庫會自動把[2021-09-01T00:00:000,+∞)裡的資料分配到db_hmTest_OrderGroup202109
2)表一定要建主鍵,不然檢索速度很慢
3)通過時間欄位做分割槽關聯列時,其它欄位不可單獨做聚合索引