我有一个后台进程,不断地实时插入表中。它可能是每小时数千个插入(有一些更新)。 Web应用程序使用此相同的表来获取显示给用户所需的一些数据。
目前,只要后台进程运行其插入/更新,Web应用程序就会被阻止,无法访问数据库。
我想知道什么是好的解决方案。我应该创建另一个我插入的表,然后将表复制到另一个只读的表中吗?还有另一种方法吗?
非常感谢任何帮助和建议!
答案 0 :(得分:4)
特别是对于SQL Server,您可能希望更改数据库以打开READ_COMMITTED_SHAPSHOT。
如果数据上有待处理的插入/更新,这基本上可以防止您的选择查询被锁定。
答案 1 :(得分:3)
要注意的一些事情是:
1)您的插入/更新或您的选择查询是否是交易的一部分?如果是这样,请确保为您的特定情况设置了最合适的transaction isolation level。
2)你在这个巨大的桌子上有太多的索引吗?索引加速选择但减慢插入和更新。确保你只有你绝对需要的索引。
3)与#2相关。您是否缺少能够加速选择的索引?您的select语句是否正在进行全表扫描?查看查询执行计划,了解实际发生的情况。 (查询分析器可以帮助您)。
4)考虑将您的巨型数据复制到一个或多个只能处理选择流量的只读数据库服务器,而读/写主表(即您现有的表)主要处理插入/更新流量。
5)您是否有可能导致性能或锁定问题的插入/更新操作触发的触发器?
6)您的应用程序是否遇到死锁事务?看一下关于这个主题的MSDN article,看看它是否有帮助。此外,请确保您了解dining philosophers problem,以便避免陷入僵局的交易。
答案 2 :(得分:1)
如果您使用的是Enterprise Edition,理想的解决方案是使用滑动窗口分区。实质上,您在同一文件组上创建一个相同的表,将数据加载到所述表中,然后将表的分区“切换”到生产表中。实际操作只是元数据翻转,因此它或多或少地瞬间发生。在这里查看更多信息: http://technet.microsoft.com/en-us/library/ms191160.aspx
答案 3 :(得分:0)
如果您只需要从Web应用程序中的表中读取数据,则可能需要尝试对查询使用READ_UNCOMMITTED隔离级别。它不需要任何锁定和读取未提交的数据。我不建议像银行应用程序那样执行此操作,但大多数典型的商业Web应用程序可能不会有问题。确保在查询后将隔离级别设置回您通常使用的(READ COMMITTED?)。
如果使用READ_UNCOMMITTED不合适,您可以熟悉Row Versioning-Based isolation levels。例如,快照隔离使用乐观方法进行数据修改,从而减少了对行进行悲观锁定的需要。