none
sqlserver2016rc1的bug?普通表和分区表在有聚集列存储索引和多个非聚集普通B树索引时的分区切换失败! RRS feed

  • 问题

  • 源表为普通表a,创建聚集列存储索引和多个非聚集普通B树索引
    目标表为分区表b,也创建聚集列存储索引和多个非聚集普通B树索引
    a和b的表结构和索引结构都一样。

    如果a和b表对应一个聚集列存储索引和1个聚集或非聚集普通B树索引,那么可以正常分区切换switch数据。
    如果a表上的普通B树索引和b表上的普通B树索引超过1个,那么切换就会失败。
    错误信息:
    消息 4947,级别 16,状态 1,第 2 行
    ALTER TABLE SWITCH 语句失败。对于目标表 'xxx.dbo.b' 中的索引 'IX_xxx',在源表 'xxx.dbo.a' 中没有完全相同的索引。

    但是其实两个表是有IX_xxx这个相同索引的。

    如果两表的B树索引只保留一个的话,就可以正常切换了。

    请确认一下是否是能解决:一个列存储索引+多个普通B树索引的分区切换问题?

    2016年3月31日 8:34

全部回复

  • 解决了,竟然要求B索引要包含分区列才可以切换。

    CREATE TABLE dbo.a
    (
    id numeric(38, 0) NOT NULL IDENTITY (1, 1),
    uid bigint NOT NULL,
    vdate smalldatetime NOT NULL,
    t nvarchar(50) NULL
    )  ON [PRIMARY]
    GO


    CREATE PARTITION FUNCTION [func_t](smalldatetime) AS RANGE RIGHT FOR VALUES (N'2016-03-29T00:00:00', N'2016-03-30T00:00:00', N'2016-03-31T00:00:00', N'2016-04-01T00:00:00', N'2016-04-02T00:00:00')
    CREATE PARTITION SCHEME [schema_t] AS PARTITION [func_t] TO ([PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY])

    CREATE TABLE [dbo].[b](
    [id] [numeric](38, 0) IDENTITY(1,1) NOT NULL,
    [uid] [bigint] NOT NULL,
    [vdate] [smalldatetime] NOT NULL,
    [t] [nvarchar](50) NULL
    ) ON [schema_t]([vdate])

    GO


    CREATE CLUSTERED COLUMNSTORE INDEX [idx_ccsi] ON [dbo].[a] WITH (DROP_EXISTING = OFF, COMPRESSION_DELAY = 0)
    CREATE NONCLUSTERED INDEX [idx_nci1] ON [dbo].[a]
    (
    [vdate] ASC
    )

    CREATE CLUSTERED COLUMNSTORE INDEX [idx_ccsi] ON [dbo].[b] WITH (DROP_EXISTING = OFF, COMPRESSION_DELAY = 0)
    CREATE NONCLUSTERED INDEX [idx_nci1] ON [dbo].[b]
    (
    [vdate] ASC
    )

    CREATE NONCLUSTERED INDEX [idx_nci2] ON [dbo].[a]
    (
    [uid] ASC
    )
    CREATE NONCLUSTERED INDEX [idx_nci2] ON [dbo].[b]
    (
    [uid] ASC
    )


    insert into a values(2,'2016-03-30','ttt')
    select * from a

    alter table dbo.a add constraint ck_a check (vdate IS NOT NULL and vdate>='2016-03-30' and vdate<'2016-03-31')


    ALTER TABLE a SWITCH TO b PARTITION 3
    select * from a
    select * from b
    --ALTER TABLE b SWITCH PARTITION 3 TO a

    消息 4947,级别 16,状态 1,第 41 行
    ALTER TABLE SWITCH 语句失败。对于目标表 'test.dbo.b' 中的索引 'idx_nci2',在源表 'test.dbo.a' 中没有完全相同的索引。

    此时drop index后可以切换分区:
    drop INDEX [idx_nci2] ON [dbo].[a]
    drop INDEX [idx_nci2] ON [dbo].[b]

    ALTER TABLE a SWITCH TO b PARTITION 3
    select * from a
    select * from b

    索引包含分区列vdate后,可以正常切换。
    CREATE NONCLUSTERED INDEX [idx_nci2] ON [dbo].[a]
    (
    [vdate] ASC,[uid] ASC
    )
    CREATE NONCLUSTERED INDEX [idx_nci2] ON [dbo].[b]
    (
    [vdate] ASC,[uid] ASC
    )

    ALTER TABLE a SWITCH TO b PARTITION 3
    ALTER TABLE b SWITCH PARTITION 3 TO a
    --成功!

    2016年3月31日 12:23
  • 源表为普通表a,创建聚集列存储索引和多个非聚集普通B树索引
    目标表为分区表b,也创建聚集列存储索引和多个非聚集普通B树索引
    a和b的表结构和索引结构都一样。

    如果a和b表对应一个聚集列存储索引和1个聚集或非聚集普通B树索引,那么可以正常分区切换switch数据。
    如果a表上的普通B树索引和b表上的普通B树索引超过1个,那么切换就会失败。
    错误信息:
    消息 4947,级别 16,状态 1,第 2 行
    ALTER TABLE SWITCH 语句失败。对于目标表 'xxx.dbo.b' 中的索引 'IX_xxx',在源表 'xxx.dbo.a' 中没有完全相同的索引。

    但是其实两个表是有IX_xxx这个相同索引的。

    如果两表的B树索引只保留一个的话,就可以正常切换了。

    请确认一下是否是能解决:一个列存储索引+多个普通B树索引的分区切换问题?


    2016年3月31日 15:59
  • 你那个索引其实是建在全表上的,不是分区上的,所以不能切换。

    想不想时已是想,不如不想都不想。

    2016年4月1日 2:40
    版主