【问题标题】:In my circumstance NOLOCK, Snapshot or something else?在我的情况下,NOLOCK,快照或其他什么?
【发布时间】:2014-09-01 06:58:05
【问题描述】:

我有一个 SQL Server 2012 表,它在任何时候都将包含 250 万行。项目总是被写入表中,但在维护窗口期间,表中最旧的行会在每天结束时被截断。

我有基于 .NET 的报告仪表板,这些仪表板通常针对汇总表进行报告,但有时它确实需要从该表中获取几行——利用索引集。

当它确实针对此表进行报告时,它可以防止将新行写入此表长达 1 分钟,这对产品非常不利。

由于它是一个报告平台,并且此表中的行永远不会更新(仅插入 - 想想 Twitter 流,但对于不同类型的数据),并不总是需要等待导致行的事务中的间隙插入到这个表中。

在选择要报告的数据时,是在事务中使用 SNAPSHOT 隔离级别来选择数据,还是 NOLOCK/READ UNCOMITTED 是明智之举?围绕 select 语句创建 SQLTransaction 会导致插入仍然阻塞吗?目前我没有将我的 SQLCommand 实例包装在事务中,尽管我意识到这仍然会导致锁定。

理想情况下,我希望写入永远不会被阻止,并且仪表板的响应速度尽可能快。我最擅长的游戏是什么?

【问题讨论】:

  • NOLOCK 不仅仅是更新行。你说这是为了报道,这些报道需要准确吗?如果可以接受丢失和/或重复的信息,您可能会没事。您永远不会处于写入永远不会被阻止的情况。当您尝试写入数据时,任何级别都可能存在也可能没有块,您的写入过程将不得不等到锁被释放。
  • 当您说准确时 - 缺少几行是否重要?不——但数字是垃圾有关系吗?绝对地!在 SNAPSHOT 事务中运行 SELECT 语句会阻止躲避但并不总是最新的结果 - 如果它会并且会提高性能,那么这听起来很理想......?
  • 隔离级别会带来一些自身的开销。快照隔离本身不会使您的查询更快。使用 NOLOCK 时,这些值不会是垃圾,但您可以并且偶尔会丢失一些行。您有时还会得到重复的行。很多时候报告这没什么大不了的,因为您可能会获得汇总数据,并且一小部分折扣并不是什么大不了的。有很多文章解释了这种行为。这个有一个正在进行的 nolock 工作示例。 jasonstrate.com/2012/06/the-side-effect-of-nolock
  • 快照隔离听起来可能非常适合您所解释的内容。对其进行一些挖掘并做出最适合您需求的选择,但我会从那里开始。

标签: sql-server database tsql data-warehouse nolock


【解决方案1】:

发布您的查询

理论上,选择不应该阻塞插入。

默认情况下,选择只需要一个共享锁。
共享锁在读操作过程中自动获取,防止用户修改数据。

这不应该阻止插入到 otherTable 或 joinTable

select otherTable.*, joinTable.*  
  from otherTable 
  join joinTable 
    on otherTable.jionID = joinTable.ID

但它确实有获取读锁的开销(它不知道你没有更新)。
但是,如果它只是从 joinTable 中获取几行,那么它应该只获取一些共享锁。
发布您的查询、查询计划和表定义。
我怀疑你有一些奇怪的事情发生,它占用的锁比它需要的多。
它可能会锁定每一行,也可能会升级为页锁或表锁。

然后看看插入。它是否需要一些不需要的疯狂锁。

【讨论】:

    猜你喜欢
    • 2015-12-24
    • 2019-12-27
    • 2019-12-16
    • 1970-01-01
    • 1970-01-01
    • 2018-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多