【问题标题】:Partition SQL table on monthly basis每月分区 SQL 表
【发布时间】:2015-07-31 11:23:58
【问题描述】:

我需要每月对 SQL 表进行分区。到目前为止,我能够在 2015 年创建 12 个分区。但是当 2016 年开始时,所有数据开始堆积在最后一个分区中(在我的例子中是 12 月)。我需要将 2016 年 1 月的数据放在 1 个分区中(在我的情况下是 1 月)。我不能每年都做分区。有什么建议吗?

【问题讨论】:

  • 调度月度作业,通过分割分区功能创建新的月度分区。详细信息将根据分区函数是 RANGE RIGHT 还是 RANGE LEFT 而有所不同,但无论哪种情况,被拆分的分区理想情况下都应该是空的(未来的日期边界)。
  • 你能提供一些例子或参考吗?
  • 我用示例脚本添加了答案。
  • @Dan Guzman 我会试一试并告诉你

标签: sql-server data-partitioning


【解决方案1】:

以下是如何为RANGE RIGHT 函数创建增量每月分区的示例,包括测试数据。

CREATE DATABASE Test;
GO

USE Test
GO

--main table partition function (before start of next month)
CREATE PARTITION FUNCTION PF_Monthly(datetime2(0))
AS RANGE RIGHT FOR VALUES (
      '2015-01-01T00:00:00'
    , '2015-02-01T00:00:00'
    , '2015-03-01T00:00:00'
    , '2015-04-01T00:00:00'
    , '2015-05-01T00:00:00'
    , '2015-06-01T00:00:00'
    , '2015-07-01T00:00:00'
    , '2015-08-01T00:00:00'
    , '2015-09-01T00:00:00'
    , '2015-10-01T00:00:00'
    , '2015-11-01T00:00:00'
    , '2015-12-01T00:00:00'
    , '2016-01-01T00:00:00' --future empty partition
)
GO

--main table partition scheme
CREATE PARTITION SCHEME PS_Monthly
    AS PARTITION PF_Monthly
    ALL TO ( [PRIMARY] );
GO


--main partitioned table
CREATE TABLE dbo.MontylyPartitionedTable(
      PartitioningColumn datetime2(0)
    , OtherKeyColumn int NOT NULL
    , OtherData int NULL
    , CONSTRAINT PK_MontylyPartitionedTable PRIMARY KEY
        CLUSTERED (PartitioningColumn, OtherKeyColumn)
        ON PS_Monthly(PartitioningColumn)
    ) ON PS_Monthly(PartitioningColumn);
GO

---load 12M rows test data
WITH
    t4 AS (SELECT n FROM (VALUES(0),(0),(0),(0)) t(n))
    ,t256 AS (SELECT 0 AS n FROM t4 AS a CROSS JOIN t4 AS b CROSS JOIN t4 AS c CROSS JOIN t4 AS d)
    ,t16M AS (SELECT ROW_NUMBER() OVER (ORDER BY (a.n)) - 1 AS num FROM t256 AS a CROSS JOIN t256 AS b CROSS JOIN t256 AS c)
INSERT INTO dbo.MontylyPartitionedTable WITH (TABLOCKX) (PartitioningColumn, OtherKeyColumn, OtherData) 
SELECT DATEADD(month, num/1000000, '20150101'), num, num
FROM t16M
WHERE num < 12000000;
GO

CREATE PROCEDURE dbo.CreateMonthlyPartition
      @NewMonthStartDate datetime2(0) --partition boundary to create
/*

*/
AS

SET XACT_ABORT ON;

BEGIN TRY

    BEGIN TRAN;

    --acquire exclusive lock on main table to prevent deadlocking during partition maintenance
    DECLARE @result int = (SELECT TOP (0) 1 FROM dbo.MontylyPartitionedTable WITH (TABLOCKX));


    --add new partition for future data
    ALTER PARTITION SCHEME PS_Monthly
              NEXT USED [PRIMARY];
    ALTER PARTITION FUNCTION PF_Monthly()
        SPLIT RANGE (@NewMonthStartDate);
    --this will release the exclusve table lock but the data in the staging table temporarily unavailable
    COMMIT;

END TRY
BEGIN CATCH

    IF @@TRANCOUNT > 0 ROLLBACK;

    THROW;

END CATCH;
GO

--schedule this before the start of each new month to create a new monthly partition 2 months in advance
SELECT DATEADD(day, 1, DATEADD(month, 1, EOMONTH(GETDATE())));
DECLARE @NewMonthStartDate datetime2(0) = DATEADD(day, 1, DATEADD(month, 1, EOMONTH(GETDATE())));

EXEC dbo.CreateMonthlyPartition @NewMonthStartDate;
GO

【讨论】:

    【解决方案2】:

    使用计算列的分区表月基数。

    **step1 : 创建 12 个月的文件组 **

    ALTER DATABASE yourDataBase ADD FILEGROUP 一月 ALTER DATABASE yourDataBase 添加文件 ( NAME = N'一月', 文件名 = N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\January.ndf' ) TO FILEGROUP 一月

    ALTER DATABASE yourDataBase ADD FILEGROUP 二月 ALTER DATABASE yourDataBase 添加文件 ( NAME = N'二月', 文件名 = N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\February.ndf', 大小 = 3072KB,文件增长 = 1024KB ) TO FILEGROUP 二月 以此类推,直到 12 个月。

    第二步:创建函数

    CREATE PARTITION FUNCTION partition_ByMonth (int) AS RANGE RIGHT FOR VALUES (2,3,4,5,6,7,8,9,10,11,12);

    第三步:创建方案

    创建分区方案 partition_scheme_ByMonth AS PARTITION partition_ByMonth TO(一月、二月、三月、四月、五月、六月、七月、八月、九月、十月、十一月、十二月);

    第四步:表分区

    ALTER TABLE PartitionTableByMonth ADD PartitionColumn as MONTH(OrderDate) PERSISTED

    第五步:索引

    在 PartitionTableByMonth (PartitionColumn) 上创建非集群索引 IX_PartitionedTable_Pd ON partition_scheme_ByMonth(PartitionColumn)

    现在你的表按月分区

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多