我目前正在处理一项棘手的任务。
背景:
- 我有一个包含多个表和大量行的 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 是不可能的。
我已经考虑过表锁在重建和修改期间不会遇到竞争条件。
我很高兴有任何解决问题的建议或帮助