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

问题
-
源表为普通表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树索引的分区切换问题?
全部回复
-
解决了,竟然要求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
--成功! -
源表为普通表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树索引的分区切换问题?