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

What is “with (nolock)” in SQL Server?

NOLOCK(Sql Server 提示)是不好的做法吗?

SQL Server 中WITH (NOLOCK)