对于我的数据库应用程序,采用快照隔离对某些查询事务似乎是解决关键要求的完美选择。
然而,我担心选择快照隔离(我相信必须在整个数据库范围内启用)会在我们开始获得非常高的数据量时带来问题。快照隔离的代价是什么?它是固定成本、线性成本还是几何成本?
如果我对高数据量感到担忧,那么是否有类似于快照隔离的应用程序级功能的策略/模式,可以具有更好的总体性能,但需要更多的时间/专业知识来实现?
谢谢,
Jason
对于我的数据库应用程序,采用快照隔离对某些查询事务似乎是解决关键要求的完美选择。
然而,我担心选择快照隔离(我相信必须在整个数据库范围内启用)会在我们开始获得非常高的数据量时带来问题。快照隔离的代价是什么?它是固定成本、线性成本还是几何成本?
如果我对高数据量感到担忧,那么是否有类似于快照隔离的应用程序级功能的策略/模式,可以具有更好的总体性能,但需要更多的时间/专业知识来实现?
谢谢,
Jason
对于那些不是锁和数据库实现专家的人来说,这可能是一个令人惊讶的难题。
我强烈推荐阅读由Hugo Kornelis(SQL Server MVP)撰写的有关快照隔离的系列文章。到目前为止,这是我见过的关于使用快照时实际考虑的最完整分析。
总结主要问题如下:
根据您编写查询的方式,甚至可能无需使用触发器就会出现意外或不一致的结果。
我不知道成本是否固定或线性,尽管它们肯定不是几何级别的; 无论如何,这都会带来一些麻烦。通常被称为“点火并忘记”选项,但事实上,如果您不知道自己在做什么,可能会出现破坏性变化(您可能直到太迟才发现!)。
如果您确定使用它不会引起其他问题,请务必使用它。但是,如果您的任何逻辑都不关心脏读取(这适用于许多系统中超过一半的SELECT
查询),则使用READ UNCOMMITTED
将获得更好的结果(这需要更多的“专业知识”-您必须非常仔细地考虑会发生什么以及何时发生)。
更新:应用级替代方案
唯一想到的替代方案是缓存。一些数据框架可以为您执行此操作(NHibernate、EF),在某些情况下,您甚至可能有第三层缓存,例如基于消息输入缓存结果的Web服务,这些结果可能基于几个查询。如果这些查询是只读的且底层数据不经常更改,我认为某种形式的缓存在您的情况下会很有效。设计考虑因素当然是您可以承受的数据量相对于您需要提供的量;如果系统非常并发,则这可能无法扩展。
除此之外,我个人不会选择尝试实现自己的应用程序级事务“层”。也许有些人已经这样做了,但我认为我的有限经验无法与数百或数千名最聪明的设计师在数据库管理系统上工作的20年相竞争。
快照隔离级别旨在比其他隔离级别更具有读取性能。通过将数据分离成快照,事务不需要在行上获取锁定,从而防止阻塞和死锁。
然而,它必须将行版本信息写入tempdb数据库。因此,每个事务都应该预计一些写入时间。
就像其他所有事情一样,您的情况将决定这是否对您更具有性能优势。如果您的应用程序是OLTP风格,则如果您的事务容易发生死锁,则可能会大幅提高性能。
READ UNCOMMITTED
恰如其分地说明了它的作用;如果你不知道这意味着什么或者不理解它的影响,请不要使用它。如果在特定情况下您可以接受脏读取,那就没问题了。 - Aaronaught