【问题标题】:SQL Server NOLOCK with JOIN, Bulk loadSQL Server NOLOCK 与 JOIN,批量加载
【发布时间】:2013-08-05 18:41:50
【问题描述】:

以下是我的场景: 我有一个通过连接 4 个表返回数据的存储过程。 中午有两次批量上传到上述 4 个表格中的一个。负载持续 10-15 分钟。我不希望调用此存储过程的 UI 在这 10-15 分钟的窗口中冻结/阻塞/减速。我不关心从上面的表中显示脏/未提交的数据。以下是我的疑问:

  1. 我需要在白天加载的表上使用 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
    
  2. 如果我在检索过程开始时添加一个 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/…

标签: sql-server join nolock


【解决方案1】:
  1. 您只需要为将要长时间锁定的表添加NOLOCK,因此仅将NOLOCK添加到Table1就足够了。
  2. 如果将隔离级别设置为READ UNCOMMITTED,则根本不需要添加NOLOCK,因为它会自动应用于所有查询的表。换句话说,您将创建类似于问题 1 中的第一个示例的情况,其中NOLOCK 应用于参与SELECT 的所有表。

顺便说一句,确保将 ON 条件添加到 INNER JOIN 子句中,因为它们不是有效的 Transact-SQL。

【讨论】:

  • 感谢迈克尔的快速简洁的回答。正是我想要的。注册 ON 条件,是的,上面是半伪代码。实际的 JOIN 确实有 ON 条件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多