Reputation: 33
I created a partitioned table in SQL Server as follows:
--Add File Groups
ALTER DATABASE TEST ADD FILEGROUP JAN;
GO
ALTER DATABASE TEST ADD FILEGROUP FEB;
GO
ALTER DATABASE TEST ADD FILEGROUP MAR;
GO
... to DEC
--create files
ALTER DATABASE [Test]
ADD FILE (NAME = N'JAN', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\Part_JAN.ndf' , SIZE = 5120KB , FILEGROWTH = 1024KB ) TO Filegroup [JAN]
ALTER DATABASE [Test]
ADD FILE ( NAME = N'FEB', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\Part_FEB.ndf' , SIZE = 5120KB , FILEGROWTH = 1024KB ) TO Filegroup [FEB]
ALTER DATABASE [Test]
ADD FILE ( NAME = N'MAR', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\Part_MAR.ndf' , SIZE = 5120KB , FILEGROWTH = 1024KB ) TO Filegroup [MAR]
... to DEC
--Create Partition Function & Partition Schema
DROP PARTITION FUNCTION partition_ByMonth
CREATE PARTITION FUNCTION partition_ByMonth (int)
AS RANGE RIGHT FOR VALUES (2,3,4,5,6,7,8,9,10,11,12) ;
GO
-- Creates a partition scheme called myRangePS1 that applies myRangePF1 to the four filegroups created above
CREATE PARTITION SCHEME Partition_Schema_ByMonth
AS PARTITION partition_ByMonth
TO (JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC) ;
GO
--Create Table
CREATE TABLE [TEST].[TEST_PS_MONTH]
(
[ID] [varchar](4) not null,
[VALUE] [varchar](30) null,
[ETL_Date] [datetime] not null,
[ETL_Month] as MONTH([ETL_Date]) PERSISTED,
CONSTRAINT(AK_TEST_PS_MONTH) UNIQUE NONCLUSTERED
([ID] ASC, [ETL_Month] ASC)
WITH (PAD_INDEX= OFF) ON Partition_Schema_ByMonth([ETL_Month])
) ON Partition_Schema_ByMonth([ETL_Month])
GO
Then I want to create clustered column stored index
---- create clustered column store index (col compression)
CREATE CLUSTERED COLUMNSTORE INDEX [IDX_TEST_PS_MONTH]
ON TEST.TEST_PS_MONTH
WITH (DROP_EXISTING = OFF, COMPRESSION_DELAY = 0) ON Partition_Schema_ByMonth([ETL_Month])
GO
But I get the following error
Msg 35307, Level 16, State 1, Line 177
The statement failed because column 'ETL_Month' on table 'TEST_PS_MONTH' is a computed column. Columnstore index cannot include a computed column implicitly or explicitly.
Is there a way to compress a table that has been partitioned by computed month?
Thanks!
Upvotes: 0
Views: 1151
Reputation: 46203
Since your objective is to maintain a 12 month sliding window based on the the ETL_Date
month, you can partition on ETL_Date
directly without a computed column. Create a partition function with initial monthly date boundaries. Then run monthly maintenance to truncate the oldest month data, remove the old boundary, and create a new boundary for the upcoming month. I suggest you use a single filegroup unless you have a need to do otherwise.
Below is an example of an initial setup for this strategy with 13 month boundaries (2020-01-01 through 2020-01-01).
CREATE PARTITION FUNCTION partition_ByMonth_Function (datetime)
AS RANGE RIGHT FOR VALUES();
CREATE PARTITION SCHEME partition_ByMonth_Scheme
AS PARTITION partition_ByMonth_Function
ALL TO ([PRIMARY]);
GO
DECLARE
@PartitionDate datetime = '20200101'
,@EndDate datetime = '20210101';
WHILE @PartitionDate <= @EndDate
BEGIN
ALTER PARTITION SCHEME partition_ByMonth_Scheme NEXT USED [PRIMARY];
ALTER PARTITION FUNCTION partition_ByMonth_Function() SPLIT RANGE(@PartitionDate);
SET @PartitionDate = DATEADD(month, 1, @PartitionDate);
END;
GO
CREATE TABLE [TEST].[TEST_PS_MONTH]
(
[ID] [varchar](4) not null,
[VALUE] [varchar](30) null,
[ETL_Date] [datetime] not null,
CONSTRAINT AK_TEST_PS_MONTH UNIQUE NONCLUSTERED
([ID] ASC, [ETL_Date] ASC)
WITH (PAD_INDEX= OFF) ON partition_ByMonth_Scheme([ETL_Date])
) ON partition_ByMonth_Scheme([ETL_Date]);
GO
CREATE CLUSTERED COLUMNSTORE INDEX [IDX_TEST_PS_MONTH]
ON TEST.TEST_PS_MONTH
WITH (DROP_EXISTING = OFF, COMPRESSION_DELAY = 0) ON partition_ByMonth_Scheme([ETL_Date])
GO
Example monthly maintenance script (remove oldest 2020-01-01 month and add new 2021-02-01 month):
DECLARE
@OldestPartitionDate datetime = '20200101'
, @NewPartitionDate datetime = '20210201';
BEGIN
TRUNCATE TABLE [TEST].[TEST_PS_MONTH] WITH(PARTITIONS ( $PARTITION.partition_ByMonth_Function(@OldestPartitionDate) ) );
ALTER PARTITION FUNCTION partition_ByMonth_Function() MERGE RANGE(@OldestPartitionDate);
ALTER PARTITION SCHEME partition_ByMonth_Scheme NEXT USED [PRIMARY];
ALTER PARTITION FUNCTION partition_ByMonth_Function() SPLIT RANGE(@NewPartitionDate);
END;
GO
Upvotes: 1