当存在非聚集列存储索引时,INSERT查询运行缓慢

时间:2018-08-06 21:01:41

标签: sql-server insert sql-server-2016

我的本​​地主机数据库中有一个很大的测试表(16 CPU,124 GB RAM),该表具有非聚集的列存储索引。我每天在此表中插入1000万行。我发现我的系统运行非常缓慢,没有结束。

我看到2个查询并行运行而没有结束,这使系统非常慢:

查询1:

INSERT INTO TABLE ABC

查询2:

ALTER NONCLUSTERED COLUMN STORED INDEX TABE ABC.

我的问题:

  1. 插入非聚集列存储索引非常慢,因为它会插入新记录并同时更改索引。正确吗?

  2. 是否需要在INSERT之前禁用INDEX并在INSERT之后启用INDEX以提高性能?

我使用SQL Server 2016,该版本允许我们使用非聚集列存储的索引来插入,更新表。

谢谢

1 个答案:

答案 0 :(得分:0)

因为根据documentation,那些不能并行运行

  

一旦在表上创建了非聚集列存储索引,就无法直接修改该表中的数据。使用INSERT,UPDATE,DELETE或MERGE的查询将失败并返回错误消息。要添加或修改表中的数据,可以执行以下操作之一:

  • 禁用列存储索引。然后,您可以更新表中的数据。如果禁用了列存储索引,则可以在完成数据更新后重建列存储索引。例如:

  • 删除列存储索引,更新表,然后使用CREATE COLUMNSTORE INDEX重新创建列存储索引。例如:

示例

ALTER INDEX mycolumnstoreindex ON mytable DISABLE;  
-- update mytable --  
ALTER INDEX mycolumnstoreindex on mytable REBUILD  


DROP INDEX mycolumnstoreindex ON mytable  
-- update mytable --  
CREATE NONCLUSTERED COLUMNSTORE INDEX mycolumnstoreindex ON mytable;  

是的,您需要在DISABLE之前的INSERTREBUILD之后的INSERT,然后 DROPINSERT之前索引,在CREATE之后再次索引INSERT。我猜运行缓慢且永不结束是与该索引分开的阻塞问题。

如果问题更笼统,对于常规NONCLUSTERED INDEX,当您尝试插入大量记录(例如您的情况下为1000万条)时,删除并重新创建索引可能是有益的,因为< / p>

  • 索引会减慢插入,更新和删除(页面拆分,插入/更新多个索引等)的速度
  • 插入很多记录可能会导致很多碎片