【问题标题】:how does SQL Server know to lock view objects?SQL Server 如何知道锁定视图对象?
【发布时间】:2012-05-04 08:16:37
【问题描述】:

在 SQL Server 2008 中,我对表 AB 有一个视图 V,看起来大致类似

create view V as
    select * from A
    union all
    select * from B

V 读取会导致查询获取基表上的意向共享锁,但也会获取视图对象上的意向共享锁。。 p>

很清楚为什么我们需要表上的 IS 锁,我们可以看到视图上的 IS 锁可以防止对视图下的表进行并发修改。没关系。

查询计划没有提及视图。它已完全编译出来,在这种情况下,生成的计划是两个基表中行的简单串联。实际上,查询计划 XML 中唯一提到视图的是语句文本。

如果您在表上添加第二个视图U,则从V 读取不会导致对U 进行任何锁定。这排除了引擎只对AB 上的所有视图进行IS 锁定。

数据库引擎如何知道要锁定视图?

  • 语句文本是否再次解析?
  • 在查询规划器和底层执行之间是否有其他信息渠道来传递这些信息?

更多详情请参阅corresponding question on dba.stackexchange

【问题讨论】:

  • 大概是从锁定视图开始,以防止在使用视图时更改视图的设计。
  • @JamieSee,那么它需要一个 S od Sch-M 锁。
  • 执行计划以二进制格式存储。并非它包含的所有内容都在显示给我们的 XML 中表示。
  • @MartinSmith 我认为这可能是答案。存储引擎知道锁定视图的机制的细节可以公平地被认为是内部的,但它这样做的事实是用户可见的,我希望它会记录在某个地方。

标签: sql sql-server sql-server-2008 view database-locking


【解决方案1】:

my answer on dba.stackexchange复制:

来自 Conor Cunningham,任何与引擎或优化器相关的东西的终极来源:

我们在编译期间跟踪事物以在运行时检查。我们不解析 为此目的执行的事情。

注意:我们从一个版本到另一个版本所做的内部工作不是 保证。这低于官方支持的表面积。

我的信念是执行计划的二进制版本(不是通过 XML 可读和公开给我们的,它只是二进制版本的一个子集)必须包含一些指向在原始查询文本(上面提到过)。它显然不是每次都解析查询文本。 Conor 暗示了上述内容,但注意不要透露有关其存储位置或方式的任何细节,因为这可能会因版本而异,甚至随着服务包或累积更新而变化。他可能也不想鼓励任何侦探工作。 :-)

【讨论】:

    【解决方案2】:

    如果查看返回 SQL Server 查询优化器详细信息的 sys.dm_exec_query_optimizer_info 视图,返回的详细信息之一是以下字段:

    视图引用 - 在查询中引用视图的次数。

    似乎某个视图被跟踪的次数某处,可能是执行计划的一部分...我的假设是,即使视图被扩展,执行计划仍然包含查询中使用了哪些视图的详细信息,并针对这些引用的视图发出适当的IS 锁。

    【讨论】:

    • 如果这些依赖项有一个单独的数据结构可能更有意义,因此当依赖对象发生更改时,它不必扫描整个计划缓存。不要认为这种程度的内部结构在任何地方都有记录。
    • @MartinSmith 我认为你是对的......就像你对问题的评论提到的那样,这些依赖关系可以包含在执行计划的二进制文件中。我搜索了一段时间,这个 DMV 是我能找到的唯一能远程解决这个问题的参考资料。
    • @MichaelFredrickson 是的,这是一个好的开始,感谢您发现这一点。我真的很想知道它是否在任何地方记录了这个视图锁定,特别是我不认为这是一个内部实现细节。恰恰相反 - 所采取的锁似乎是通过视图读取语义的可见部分。
    【解决方案3】:

    默认情况下,视图会像宏一样展开到引用它们的查询中。

    这可以被关闭,或者如果它们被具体化等,则可以改变,但类似宏的内联扩展是常态。这意味着锁定等的行为就像您执行了以下操作一样......

    SELECT
      *
    FROM
      blah
    INNER JOIN
    (
      yourViewCode
    )
      AS aView
        ON aView.id = blh.id
    

    【讨论】:

    • 但它没有表现得像这样。
    • 这可能是一个很好的理解方便,但视图是在创建时编译的。如果基础表更改,默认情况下视图不会更改。特别是,由于这个原因,您应该避免在视图中“选择 *”。
    • @Dems 我知道视图是这样扩展的,我不是在谈论超出此规范或物化视图的行为。无论如何,正如 usr 指出的那样,这不是我要问的行为。
    • @GordonLinoff 尽管在视图中 select * 的优点,但显然这只是一个简单方便的视图示例 - 这与问题无关。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-29
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 2013-12-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多