在SQL Server 2008中,我对表V
和A
的视图B
看起来大致相似
create view V as
select * from A
union all
select * from B
从V
读取会导致查询在基表上意图共享锁,但也会在视图对象本身上执行意图共享锁定。
很清楚为什么我们需要表上的IS锁,我们可以看到视图上的IS锁阻止了对视图底层表的并发修改。没关系。
查询计划不包含视图。它已完全编译出来,在这种情况下生成的计划是两个基表中的行的简单连接。实际上,查询计划XML中唯一提到的视图是在语句文本中。
如果您在表格上添加第二个视图U
,则从V
读取不会导致U
上的任何锁定。这排除了引擎只对A
和B
上的所有视图进行IS锁定。
数据库引擎如何知道对视图进行锁定?
有关详细信息,请参阅corresponding question on dba.stackexchange
。
答案 0 :(得分:3)
从my answer on dba.stackexchange复制:
来自Conor Cunningham,任何引擎或优化器相关的最终来源:
我们在编译期间跟踪事物以在运行时检查。我们不解析 为此目的执行的事情。
注意:我们从一个发行版到另一个发行版的内部结构不是 保证。这是在官方支持的表面区域之下。
我认为执行计划的二进制版本(不是通过XML可读和暴露给我们的二进制版本,它只是二进制版本的一个子集)必须包含一些指向视图的指针。原始查询文本(这是上面提到的)。显然每次都不解析查询文本。 Conor意味着上述内容,但小心不要透露有关存储位置或方式的任何详细信息,因为这可能会在发行版之间发生变化,甚至可能随服务包或累积更新而变化。他可能也不想鼓励任何侦探工作。 : - )
答案 1 :(得分:2)
如果查看返回SQL Server查询优化器详细信息的sys.dm_exec_query_optimizer_info
视图,则返回的详细信息之一是以下字段:
查看参考 - 查询中引用视图的次数。
看起来引用视图的次数某处,可能作为执行计划的一部分......我的假设是,即使视图被扩展,执行计划也是如此仍包含查询中使用的视图的详细信息,并针对这些引用的视图发出相应的IS
锁。
答案 2 :(得分:0)
默认情况下,视图会像宏一样展开到引用它们的查询中。
这可以关闭,或者如果它们具体化则会有所不同等,但是像宏一样的内联扩展是常态。这意味着锁定等行为就像您执行以下操作一样......
SELECT
*
FROM
blah
INNER JOIN
(
yourViewCode
)
AS aView
ON aView.id = blh.id