1

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

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

用于创建 View 的 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时查询执行时间减少了这么多(与不使用视图相比(即使我们DBCC DROPCLEANBUFFERS()在执行查询之前运行到VIEW))
2.更改后

Table2_DeletedMark 

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

4

2 回答 2

2

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

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

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

于 2010-12-10T11:29:15.050 回答
0

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

于 2010-12-10T11:57:54.157 回答