1

我目前正在处理一项棘手的任务。

背景:

  • 我有一个包含多个表和大量行的 MSSQL 2012 数据库。由于在此数据库中搜索需要相当长的时间,因此我寻找改进查询的方法。(是的,我正在使用索引,已经查看了执行计划和类似的东西:-))经过一番调查,我在 MSSQL 2012 Enterprise 中找到了列存储索引。这让我在搜索过程中获得了巨大的性能提升。
  • 缺点:启用索引后,无法插入/更新/删除数据

目标:

  • 我想要快速搜索
  • 应该可以一次运行多个工作人员来插入/更新/删除具有列存储索引的数据(在访问相同 表的多个工作人员之间拆分工作)(通常在夜间完成)
  • 工作人员完成任务执行索引后,应重建(其他工作人员应等到那时)
  • 之后工作人员应继续并在必要时再次禁用索引

当前解决方案:

目前有一个解决方案,但它不能 100% 工作,因为仍然会收到有时无法执行 UPDATES 和 INSERTS 的消息,因为应该首先禁用列存储索引(但它们应该根据我所做的)或者那里是在调用存储过程以操作数据期间出现的死锁。

一个简短的概述我做了什么。我不确定它是否是使用列存储索引更新表的最佳方法。还阅读了有关分区切换的信息,但当前未使用分区(由于数据结构和搜索)

我在 MSSQL 数据库中有以下存储过程。

sp_columnstore_entity_disable(禁用表上的索引)

ALTER INDEX [ColumnStoreIndex_Entity] ON dbo.[Entity] DISABLE

sp_columnstore_entity_rebuild(重建表上的索引)

ALTER INDEX [ColumnStoreIndex_Entity] ON dbo.[Entity] REBUILD

sp_entity_insert_update

-- Whenever this stored procedure is executed index should be disabled in case it active
EXEC sp_columnstore_entity_disable

-- Insert or Update the entity

worker 的程序代码如下所示:

// get entities to process
for(int i = 0; i < num_entities; i++)
{
   // do some work
   // insert / update entity
}

// Rebuild column store indexes again
DBRebuildColumnStoreIndexes();

问题:

有时我会收到错误消息,例如事务(进程 ID)在锁定资源上与另一个进程死锁,并被选为死锁受害者,我的进程崩溃。

有时我会收到错误,因为列存储索引处于活动状态,所以 INSERT 或 UPDATE 是不可能的。

我已经考虑过表锁在重建和修改期间不会遇到竞争条件。

我很高兴有任何解决问题的建议或帮助

4

1 回答 1

0

在我的旧团队中,我们正在考虑为我们想要执行数据仓库任务的存档记录建立列存储索引,但是该数据库是一个高度事务性的数据库,需要 24/7 的正常运行时间。我们的解决方案是设置一个 ETL 流程,将数据转储到一个单独的数据仓库数据库中,我们在该数据库上启用了列存储索引。也就是说,我们使用 2014 并启用了允许插入/更新/删除的聚集列存储索引,但将其放在单独的表中允许对表和索引进行维护任务而不影响操作。

根据我的经验,最好有一个专门的数据库用于操作,一个单独的数据库用于报告。尤其是在操作上,您可以归档大量您希望保留以供报告的记录。

于 2017-06-29T00:50:39.400 回答