SQL Server NOLOCK 与 JOIN,批量加载
Posted
技术标签:
【中文标题】SQL Server NOLOCK 与 JOIN,批量加载【英文标题】:SQL Server NOLOCK with JOIN, Bulk load 【发布时间】:2013-08-05 18:41:50 【问题描述】:以下是我的场景: 我有一个通过连接 4 个表返回数据的存储过程。 中午有两次批量上传到上述 4 个表格中的一个。负载持续 10-15 分钟。我不希望调用此存储过程的 UI 在这 10-15 分钟的窗口中冻结/阻塞/减速。我不关心从上面的表中显示脏/未提交的数据。以下是我的疑问:
我需要在白天加载的表上使用 NOLOCK 还是需要将 NOLOCK 添加到连接的所有 4 个表中。 例如
SELECT *
FROM Table1 T1 WITH (NOLOCK) --this is the table that will be bulk-loaded twice during the day
INNER JOIN Table2 T2 WITH (NOLOCK)
INNER JOIN Table3 T3 WITH (NOLOCK)
INNER JOIN Table4 T4 WITH (NOLOCK)
或者这样就够了
SELECT *
FROM Table1 T1 WITH (NOLOCK) --this is the table that will be bulk-loaded twice during the day
INNER JOIN Table2 T2
INNER JOIN Table3 T3
INNER JOIN Table4 T4
如果我在检索过程开始时添加一个 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 并在最后将其重置为 READ COMMITTED,会有什么不同吗?
谢谢
维卡斯
【问题讨论】:
@MartinSmith 不正确。只有 Sch_M 锁会阻止读取未提交的只读查询。 @SebastianMeine - 你说得对,我认为它需要一个IS
锁定而不是 SCH-S
锁定。
另外请记住,SCH-M 不仅仅用于模式更改。它可以用于离线重新索引、截断和偶尔的批量插入。请参阅此处了解何时可以在批量插入批量或简单恢复模型期间采用 SCH-M:technet.microsoft.com/en-us/library/…
【参考方案1】:
-
您只需要为将要长时间锁定的表添加
NOLOCK
,因此仅将NOLOCK
添加到Table1
就足够了。
如果将隔离级别设置为READ UNCOMMITTED
,则根本不需要添加NOLOCK
,因为它会自动应用于所有查询的表。换句话说,您将创建类似于问题 1 中的第一个示例的情况,其中NOLOCK
应用于参与SELECT
的所有表。
顺便说一句,确保将 ON
条件添加到 INNER JOIN
子句中,因为它们不是有效的 Transact-SQL。
【讨论】:
感谢迈克尔的快速简洁的回答。正是我想要的。注册 ON 条件,是的,上面是半伪代码。实际的 JOIN 确实有 ON 条件。以上是关于SQL Server NOLOCK 与 JOIN,批量加载的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server 中的“with (nolock)”是啥?
HSQLDB Junit 测试对 DB2 和 SQL Server NOLOCK 查询失败
[SQL SERVER][Performance]小心使用With NoLock