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), DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0), 120)+''')'
    EXEC (@sql);
END;
GO

雜項列表

1)db_hmTest_OrderGroup202108會包含[2021-08-01T00:00:000,+∞)。后期動態新增文件組時,數據庫會自動把[2021-09-01T00:00:000,+∞)里的數據分配到db_hmTest_OrderGroup202109
2)表一定要建主鍵,不然檢索速度很慢
3)通過時間字段做分區關聯列時,其它字段不可單獨做聚合索引


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM