切换数据分区时出现“无相同索引”错误

时间:2009-07-01 23:36:02

标签: sql-server tsql

我正在尝试设置一个数据仓库应用程序,以便我的公司使用分区数据导入表。我试图删除旧数据并为新数据腾出空间。这是我收到此错误消息的地方:

Msg 4947, Level 16, State 1, Line 1 ALTER TABLE SWITCH statement failed. There is no identical index in source table 'AssetServer.dbo.IISLog061122' for the index 'IDX_IISLogPartitioned_IP' in target table 'AssetServer.dbo.IISLogPartitioned' . 

以下是需要复制的索引的定义

/ ******对象:索引[IDX_IISLogPartitioned_IP]脚本日期:07/01/2009 10:44:45 ****** /

CREATE NONCLUSTERED INDEX [IDX_IISLogPartitioned_IP] ON [dbo].[IISLogPartitioned] ( 
[c-ip] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) 

下面你会看到我在存储过程中创建了一个相同的索引。我已经验证它已成功创建,但alter table语句失败并显示上述消息。存储过程的主循环归结为:

ALTER PARTITION FUNCTION fnIISLogRequestTime() SPLIT RANGE ('20090612 01:59:59:000');

CREATE TABLE [dbo].[IISLog061201]     
    ([RequestTime] [datetime] NULL,     
     [weekday] [int] NOT NULL,     
     [cs-method] [varchar](50) NOT NULL,     
     [cs-uri-stem] [varchar](255) NOT NULL,     
     [cs-uri-query] [varchar](2048) NULL,     
     [c-ip] [varchar](50) NOT NULL,     
     [cs(Referer)] [varchar](2048) NULL,     
     [cs-host] [varchar](255) NULL,     
     [sc-status] [int] NOT NULL,     
     [sc-substatus] [int] NULL,     
     [sc-bytes] [int] NULL,     
     [cs-bytes] [int] NULL,     
     [time-taken] [int] NULL,     
     [insertiontime] [datetime] NOT NULL,     
     [TimeSinceLast] [int] NULL,     
     [VIP] [varchar](50) NULL) ON [PRIMARY];      



CREATE NONCLUSTERED INDEX [IDX_IISLogPartitioned_IP] ON [dbo].[IISLog061201](
    [c-ip] ASC
) WITH (
    PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, 
    SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, 
    DROP_EXISTING = OFF, ONLINE = OFF, 
    ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON);


ALTER TABLE [dbo].[IISLog061201] SWITCH TO IISLogPartitioned PARTITION 7

如何摆脱此错误消息?

2 个答案:

答案 0 :(得分:5)

您收到错误的原因是因为这两个索引实际上相同。分区表上的索引在其定义中包含分区列,即使您的代码没有明确说明它。 (这是一个幕后的事情。)

如果要在分区表时进行分区切换,则索引需要显式引用分区列。更改您提供的索引包括RequestTime(假设这是分区列)。您可以将其作为索引列或仅包含列。下面我去包括。

CREATE NONCLUSTERED INDEX [IDX_IISLogPartitioned_IP] ON [dbo].[IISLog061201](
[c-ip] ASC) INCLUDE ( RequestTime ) WITH (
PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, 
SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, 
DROP_EXISTING = OFF, ONLINE = OFF, 
ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON);

现在应该可以了。

答案 1 :(得分:0)

根据您的文字,似乎此代码在存储过程中?

或许问题是程序在某个时刻被重新编译 - 它注意到了索引问题。即使您稍后可能创建索引,它也无法工作,因为编译失败。

如果向一个过程中的表添加一个列并稍后加入此列,则会发生同样的事情:有时它可能会起作用,因为没有重新编译,但有时它不会因为(例如因为不同的数据集)重新编译完成。

有时这些问题可以通过使用动态SQL和sp_executesql来解决,或者您可以将代码拆分为两个SP。或者,如果不真正需要SP,只需将脚本分成不同的部分即可。