13

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

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

读取 fromV会导致查询在基表上获取意向共享锁,但也会在视图对象本身上获取意向共享锁。

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

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

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

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

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

有关详细信息,请参阅相应的问题dba.stackexchange

4

3 回答 3

4

复制我在 dba.stackexchange 上的回答

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

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

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

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

于 2012-04-25T15:01:35.227 回答
2

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

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

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

于 2012-04-23T19:24:24.333 回答
0

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

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

SELECT
  *
FROM
  blah
INNER JOIN
(
  yourViewCode
)
  AS aView
    ON aView.id = blh.id
于 2012-04-23T17:42:57.760 回答