在 SQL Server 2017 上创建具有 800+ 百万行的现有分区表的列存储索引

Posted

技术标签:

【中文标题】在 SQL Server 2017 上创建具有 800+ 百万行的现有分区表的列存储索引【英文标题】:Creating columnstore Index on existing partitioned table with 800+ million rows on SQL Server 2017 【发布时间】:2020-04-03 07:51:09 【问题描述】:

我有包含超过 8 亿行的 B-Tree 聚集索引的分区表(日期)。

我想在这个表上创建一个聚集列存储索引来代替现有的聚集索引,最有效的方法是什么?

这会影响我使用 B-tree 聚集索引创建的现有主键吗?

我还需要做什么才能使我的列存储索引与表的现有分区对齐?

请指导。

 CREATE TABLE [dbo].[ORDHDR](
        [DATE_DWID] [bigint] NOT NULL,
        [VERSION] [bigint] NOT NULL,
        [LOCATION_DWID] [bigint] NOT NULL,
        [START_LOC_DWID] [bigint] NOT NULL,
        [DESTINATION_LOC_DWID] [bigint] NOT NULL,
        [XFY_ID] [bigint] NOT NULL,
        [START_DWID] [bigint] NOT NULL,
        [END_DWID] [bigint] NOT NULL,
        [START_REQ_DWID] [bigint] NOT NULL,
        [END_IYF_DWID] [bigint] NOT NULL,
        [CREATED_AT_DWID] [bigint] NOT NULL,
        [TIME_OF_IPB_DWID] [bigint] NOT NULL,
        [DATAREC_NUM] [int] NOT NULL,
        [REQUEST_FOR_DATA_TRANSFER] [varchar](30) NULL,
        [DATAPCKT_NUM] [varchar](6) NOT NULL,
        [INTERNAL_NUM_FOR_SUPPLY] [varchar](30) NULL,
        [SOURCE_SUPPLY] [varchar](60) NULL,
        [RECORD_MODE] [varchar](1) NULL,
        [ORD_TYPE] [varchar](3) NULL,
        [APO_ORD] [varchar](12) NULL,
        [APO_APPLICATION] [int] NULL,
        [SUPPLY_CATEGORY] [varchar](12) NULL,
        [CONVERTABLE_ORD] [varchar](1) NULL,
        [ORDSTATUS_OUTPUT] [varchar](1) NULL,
        [ORDSTATUS_INPUT] [varchar](1) NULL,
        [PARTIAL_DELIVERY_STATUS] [varchar](1) NULL,
        [FINAL_DELIVERY_INDICATOR] [varchar](1) NULL,
        [STATUS_DEALLOCATED] [varchar](1) NULL,
        [STATUS_RELEASED] [varchar](1) NULL,
        [STATUS_FIXED] [varchar](1) NULL,
        [STATUS_STARTED] [varchar](1) NULL,
        [ORD_COMPONENT_ISSUED] [int] NULL,
        [PARTIALLY_CONFIRMED] [varchar](1) NULL,
        [FINAL_CONFORMATION] [varchar](1) NULL,
        [ORD_PLNG_TYPE] [int] NULL,
        [ORD_STATUS] [int] NULL,
        [START_TIME_OF_ACTIVITY] [varchar](15) NULL,
        [END_DATE_OF_LATEST_ACTIVITY] [varchar](15) NULL,
        [FLAG] [varchar](1) NULL,
        [EDW_CREATE_DATE] [datetime] NULL,
        [EDW_UPDATE_DATE] [datetime] NULL
    ) ON [ORD_PS]([DATE_DWID])

    GO

    CREATE UNIQUE CLUSTERED INDEX [ORD_HDR_PK] ON [dbo].[ORDHDR]
    (
        [DATE_DWID] ASC,
        [VERSION] ASC,
        [LOCATION_DWID] ASC,
        [START_LOC_DWID] ASC,
        [DESTINATION_LOC_DWID] ASC,
        [XFY_ID] ASC,
        [START_DWID] ASC,
        [END_DWID] ASC,
        [START_REQ_DWID] ASC,
        [END_IYF_DWID] ASC,
        [CREATED_AT_DWID] ASC,
        [TIME_OF_IPB_DWID] ASC,
        [DATAREC_NUM] ASC,
        [DATAPCKT_NUM] ASC
    )

【问题讨论】:

为了清楚起见,将现有表的 DDL 添加到您的问题中。您提到现有表按日期分区并具有聚集主键索引。这意味着现有的聚集主键包括分区列,假设索引是对齐的。您要完全删除现有的主键吗? 我想要所有现有的键和约束。我唯一想要的是将现有的 B 树聚集索引转换为列存储聚集索引。及其对现有设计的影响。我已经添加了 DDL 我在您的 DDL 中看不到主键或任何其他约束。你说的主键是指唯一聚集索引吗? 【参考方案1】:

由于聚集列存储索引只有列而没有键,您需要将现有的唯一聚集索引更改为聚集列存储索引,以将行存储表转换为列存储,然后创建新的非聚集 b-tree索引以强制唯一性。

这可以通过CREATE CLUSTERED COLUMNSTORE INDEXDROP_EXISTING=ON 子句然后创建新索引来完成。

--change existing clustered index to clustered columnstore
CREATE CLUSTERED COLUMNSTORE INDEX ORD_HDR_PK ON [dbo].[ORDHDR]
    WITH(DROP_EXISTING=ON) ON [ORD_PS]([DATE_DWID]);

--rename columnstore index to a more meaningful name
EXEC sp_rename 'dbo.ORDHDR.ORD_HDR_PK','ccidx_ORDHDR', 'INDEX';

--create new non-clustered unique index
CREATE UNIQUE NONCLUSTERED INDEX [ORD_HDR_PK] ON [dbo].[ORDHDR]
    (
        [DATE_DWID] ASC,
        [VERSION] ASC,
        [LOCATION_DWID] ASC,
        [START_LOC_DWID] ASC,
        [DESTINATION_LOC_DWID] ASC,
        [XFY_ID] ASC,
        [START_DWID] ASC,
        [END_DWID] ASC,
        [START_REQ_DWID] ASC,
        [END_IYF_DWID] ASC,
        [CREATED_AT_DWID] ASC,
        [TIME_OF_IPB_DWID] ASC,
        [DATAREC_NUM] ASC,
        [DATAPCKT_NUM] ASC
    ) ON [ORD_PS]([DATE_DWID]);

【讨论】:

我的主要目的是在创建列存储索引时如何处理底层表分区。 当使用相同的分区方案时,分区将与行存储和列存储相同。此外,新的非聚集 b-tree 索引使用相同的方案进行分区,因此列存储表和 b-tree 索引对齐。 Dan,能否请您指导我维护集群列存储索引。这就是我们如何有效地使该索引与碎片和统计信息等保持同步。 考虑使用这个受欢迎的maintenance solution。

以上是关于在 SQL Server 2017 上创建具有 800+ 百万行的现有分区表的列存储索引的主要内容,如果未能解决你的问题,请参考以下文章

Windows版 SQL Server 2017 AlwaysOn AG 自动初始化测试报告

具有不同排序方向的多列上的Sql server聚集索引

Linux下安装SqlServer 2017SQL Server on Linux

SQL Server 2017 AlwaysOn AG 自动初始化

无法使用 OPENJSON 和 SQL Server 2017 解析具有动态键的对象数组

Ubuntu下部署SQL Server 2017