3

我在测试 sql server 2012 的列存储索引功能时很开心。因为您无法使用此类索引更新/插入表,所以我阅读了一些选项:保留一个单独的表并为每个批量插入使用新分区或禁用索引,执行更新/插入,然后重建索引。

对于我的测试,我选择了后一个选项并最终得到了这个存储过程:

-- Disable the columnstore index.
ALTER INDEX [All_Columns_Columnstore_Index] ON [dbo].[Tick] DISABLE

-- Insert data into tick table from staging table.
insert into Tick
select [Date],
       SymbolID,
       Price
from TickTemporary

-- Delete data from staging table.
delete from TickTemporary

-- Enable (rebuild) the columnstore index.
ALTER INDEX [All_Columns_Columnstore_Index] ON [dbo].[Tick] REBUILD

如果我手动执行这些行,一切正常。但是,如果我运行该过程,则会收到无法在具有列存储索引的表上执行更新/插入的错误。

为什么是这样?

更新:

我遵循了我之前接受的答案中的建议,但我仍然得到同样的结果。

-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

-- Disable the columnstore index.
EXEC DisableColumnStoreIndex

-- Insert data into tick table from staging table.
insert into Tick
select [Date],
       SymbolID,
       Price
from TickTemporary

-- Delete data from staging table.
delete from TickTemporary

-- Enable (rebuild) the columnstore index.
EXEC RebuildColumnStoreIndex

甚至尝试在 sproc 调用周围放置“begin tran”和“commit tran”。

使用动态 sql,如:

declare @sql nvarchar(max)
set @sql =
    'insert into Tick
     select [Date],
            SymbolID,
            Price
     from TickTemporary'
exec(@sql)

有效,但实际上,我想在没有动态 sql 的情况下过日子。在这种情况下不可能吗?

4

2 回答 2

4

检查是在编译时完成的,而不是在执行时完成的。将过程分离成自己的,或使用动态 SQL。

但作为一般性评论,这不是正确的方法。您应该插入具有相同结构的不同表,在此相同表上构建列存储索引,然后使用分区切换将旧表替换为新表:用空表切换旧表,切换新表,把旧数据丢掉。类似于如何使用列存储索引更新表中描述的过程。由于使用了分区切换,您的表用户会经历更短的停机时间,因为旧表在插入和构建列存储阶段期间仍然在线并且可用。

于 2012-10-29T07:55:32.957 回答
1

此编译时执行的解决方案是 Option(recompile)

create  PROCEDURE TEST
AS
BEGIN

ALTER INDEX [All_Columns_Columnstore_Index] ON [dbo].[Tick] DISABLE

-- Insert data into tick table from staging table.

insert into Tick
select [Date],
       SymbolID,
       Price
from TickTemporary  **Option(recompile)**

-- Delete data from staging table.
delete from TickTemporary

-- Enable (rebuild) the columnstore index.
ALTER INDEX [All_Columns_Columnstore_Index] ON [dbo].[Tick] REBUILD

End
于 2015-01-07T06:28:00.607 回答