在 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 实体?

在Linq-to-SQL中使用WHERE子句时出错

使用 SQL Server Compact Edition 的 Linq-to-SQL

通过 LINQ-to-SQl 加载数据集

使用 Linq-to-SQL 的 ADO.NET 数据服务

为啥 Linq-to-sql 错误地删除了我的联合中的字段?