了解 SQL Server 2008 R2 中的索引视图更新和查询过程

Posted

技术标签:

【中文标题】了解 SQL Server 2008 R2 中的索引视图更新和查询过程【英文标题】:Understanding indexed view update qnd query process in SQL Server 2008 R2 【发布时间】:2010-12-10 11:18:15 【问题描述】:

我用这样的 T-SQL 创建了索引视图(Table1_ID 上的聚集唯一索引)视图:

Select Table1_ID, Count_BIG(*) as Table2TotalCount from Table2 inner join
Table1 inner join... where Table2_DeletedMark=0 AND ... Group BY Table1_ID

同样在创建视图之后,我们在 Table1_ID 列上设置了聚集唯一索引。 所以 View 由两列组成:

Table1_ID
Table2TotalCount

用于创建视图的 T-Sql 很重​​,因为 Table2 中的 group by 和数百万行。

但是当我对像

这样的视图运行查询时
Select Total2TotalCount from MyView where Table1_ID = k

- 它执行速度快,而且没有服务器开销。

还在 t-sql 中为 Table2 列的 where 子句创建视图的许多条件。和 如果我将 Table2_DeletedMark 更改为 1 并运行查询

Select Total2TotalCount from MyView where Table1_ID = k

再次 - 我会得到正确的结果。 (Table2TotalCount 减 1)。

所以我们的问题是: 1. 为什么我们使用Indexed View时查询执行时间减少了这么多(与不使用视图相比(即使我们在对VIEW执行查询之前运行DBCC DROPCLEANBUFFERS())) 2.更改后

Table2_DeletedMark 

视图立即重新计算,我们得到正确的结果,但背后的过程是什么?我们无法想象每次我们更改 t-sql 视图生成中包含的 10+ 列的任何值时,sql 都会根据生成的视图执行 t-sql,因为它太重了。 我们知道,运行一个简单的查询来重新计算值就足够了,这取决于我们更改的列值。 但是sql怎么理解呢?

【问题讨论】:

【参考方案1】:

索引视图是物化,例如它包含的行(来自它所依赖的表)物理存储在磁盘上——就像一个“系统计算的”表,只要其基础表发生变化,它就会始终保持最新状态。这是通过添加聚集索引来完成的 - SQL Server 表(或视图)上的聚集索引的叶页实际上是数据页。

索引视图中的列也可以使用非聚集索引进行索引,因此您可以进一步提高查询性能。不利的一面是:由于存储了行,因此您需要磁盘空间(显然,有些数据是重复的)。

另一方面,普通视图只是 SQL 的一个片段,将根据您从该视图中选择的内容执行计算结果。该视图没有物理表示,没有为常规视图存储的行 - 它们需要根据需要从基表连接在一起。

【讨论】:

我知道索引视图是物化的。主要问题是我们的第二个问题。我想知道一种机制可以“在其基础表更改时始终保持最新”。这个怎么运作 ?你能解释一下问题2吗 @mmcteam.com.au:除了 SQL Server 团队的某个人,我认为没有人能真正详细解释它是如何工作的。我只知道它确实有效 - 每当更改任何基础表时,都会更新索引视图。这就是我需要了解的全部内容:-)【参考方案2】:

为什么您认为关于索引视图中允许什么以及允许基表做什么有这么多奇怪的规则?这样 SQL 引擎可以立即知道“如果我正在触摸这一行,它可能会影响该视图的结果 - 让我们看看,该行不再符合视图标准,但我坚持要有一个 COUNT_BIG(*),所以我可以将该值减一”

【讨论】:

以上是关于了解 SQL Server 2008 R2 中的索引视图更新和查询过程的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 2008 中的 SQL Server 2008 R2 中的 dm_os_volume_stats 等效项是啥?

从 Win CE 设备到 SQL Server 2008 R2 的 SQL 复制

SQL Server 2008 R2 中的自动更新统计信息和 FULLSCAN

如何在 SQL Server 2008 R2 中的 select 语句中编写条件

SQL Server Management Studio 2008 R2 中的查询分析器在哪里?

根据 SQL Server 2008R2 中表中的列获取计数