在 LINQ-To-SQL 中,我应该使用 NOLOCK 来提高性能吗?
Posted
技术标签:
【中文标题】在 LINQ-To-SQL 中,我应该使用 NOLOCK 来提高性能吗?【英文标题】:In LINQ-To-SQL, should I use NOLOCK to improve performance? 【发布时间】:2011-02-18 16:43:38 【问题描述】:我们的 DBA 告诉我们,我们的 LINQ 查询正在数据库上创建数以千计的锁。我们团队的一位开发人员挖掘了这篇 Hanselman 帖子作为我们问题的可能解决方案:
http://www.hanselman.com/blog/GettingLINQToSQLAndLINQToEntitiesToUseNOLOCK.aspx
Scott 在 LINQ 中提供了 3 种方式来设置 NOLOCK。 1) TransactionScope (首选), 2) SPROCS, 3) context.ExecuteCommand
我们是一个 99% 读取率和 1% 写入率的新闻网站,因此我们主要关注检索速度。 NOLOCK 是我们所有 LINQ-TO-SQL 查询的好策略吗?
我想了解的是为什么使用 NOLOCK 是或不是一个好主意。肯定有很多人有着相同的目标:很多快速阅读,很少甚至没有更新。如果 NOLOCK 是显而易见的答案,那么为什么它不是默认值呢?为什么我不能在上下文中将其设为默认值,而不必在每个数据调用中都设置它?
对于阅读速度快、更新少的网站来说,NOLOCK 真的是最佳选择吗?
更新:在 SQL Server 2005 及更高版本中,快照隔离是否优于 NOLOCK? 我刚发现这个 http://msdn.microsoft.com/en-us/library/ms179599.aspx
其中包括READ COMMITTED SNAPSHOT。这可以防止写块,但不返回脏数据?是否应该在 NOLOCK 上 90% 的时间使用它?
更新 2:困扰我的是干燥
最困扰我的部分是,为了实现无锁或快照模式,我必须在每个 LINQ-to-SQL 查询方法(更新中使用的除外)上更改它。这闻起来像是严重违反 DRY。
【问题讨论】:
这对它的速度有好处 - 它很糟糕,因为您最终可能会取回尚未提交的数据(“脏数据”),并且最终可能会被回滚而不是持久化...... 未提交数据如何返回的示例是什么?作为事务的一部分完成但回滚的写入? 是的,如果您碰巧在其他人在事务中向其写入数据的过程中读取了该表,您将取回未提交的数据,这可能是不完整的,或者其他进程可能然后决定最后回滚事务,因此您的读取最终得到了一些不在表中的数据.. 在右侧的“相关”窗格中,有大约 2 打关于 NOLOCK 的问题。 【参考方案1】:值得注意的是:READ COMMITTED SNAPSHOT
(或至少 2 年前)对于the site you're using 来说已经足够好了。
【讨论】:
以上是关于在 LINQ-To-SQL 中,我应该使用 NOLOCK 来提高性能吗?的主要内容,如果未能解决你的问题,请参考以下文章
在 BLL 或 UI 中使用 Linq-to-SQL 实体?