在 JOIN 查询中的某些表上使用 WITH (NOLOCK)

Posted

技术标签:

【中文标题】在 JOIN 查询中的某些表上使用 WITH (NOLOCK)【英文标题】:Using WITH (NOLOCK) on some tables in a JOIN query 【发布时间】:2017-11-03 09:44:05 【问题描述】:

我已阅读有关此和事务隔离级别的信息,只是想知道.....

我有一些针对产品、类别、位置和库存的查询。 现在产品、类别和位置数据很少发生变化,但您可以想象,库存会发生变化。 在产品、类别、位置上指定WITH (NOLOCK) 而不在 Stock 上指定是否合理? 我做了一些计时,它似乎确实提高了性能,所以我很高兴。

我的理解是,如果我没有在 Stock 上指定 WITH (NOLOCK),那只会得到已提交的事务,而不会出现脏读。 同时,由于其他表格的内容很少改变,指定WITH (NOLOCK) 是安全的。

我正在处理的特定过程不会写入任何提到的表......它将一些结果放入#table并从中返回行。

感谢您的想法。

【问题讨论】:

就个人而言,我不会使用 NOLOCK 来提高性能。索引和查询调优通常是提高性能的最佳方式。 我听到你的声音,但有时我们只能改变我们可以控制的东西 ;) 我明白利弊......在提到的情况下,考虑到使用涉及的问题。从长远来看,你是对的,但现在...... 【参考方案1】:

用 NOLOCK 只放锁 Sch-S(模式稳定)

不带 NOLOCK S 锁 + Sch-S 但是 NOLOCK 会给出 READ UNCOMMITTED 数据(脏读),这会给你不正确的数据。

https://sqlstudies.com/2015/03/18/why-not-nolock/

使用 RSCI (Read Committed Snapshot Isolation) 行版本控制实现读已提交隔离级别 https://sqlperformance.com/2014/05/t-sql-queries/read-committed-snapshot-isolation

【讨论】:

不错的文章 Tapakah,但我所说的没有在 Stock 表上指定提示是否正确? 是的,只有带有提示的表返回未提交的数据 小步骤。我认为我可以在存储过程级别上非常安全地进行更改,而不会影响其他任何内容。关于快照隔离级别,这可能是与 DBA 的会议。感谢您提供信息,祝您周末愉快。 我想你的意思是Sch-S(模式稳定性)锁。 Schema 修改锁实际上是数据库对象的排他锁。 操作,当然是 Sch-S :)

以上是关于在 JOIN 查询中的某些表上使用 WITH (NOLOCK)的主要内容,如果未能解决你的问题,请参考以下文章

为啥 count(*) 查询在某些表上很慢,而在其他表上却没有?

BigQuery JOIN 在两个表上

优化 30 000+ 行表上的 LEFT JOIN

MySQL Left Join Subquery with *

删除左表上的重复项,同时在右表SELECT JOIN上保留重复项

INNODB FULLTEXT 使用 JOIN 搜索:不同表上的搜索词