我用这样的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
用于创建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.当我们使用索引视图时,为什么查询执行时间减少了很多(比较没有查看使用(甚至我们在向VIEW执行查询之前运行DBCC DROPCLEANBUFFERS()
))
2.更改后
Table2_DeletedMark
立即重新计算,我们得到了正确的结果,但背后的过程是什么?我们无法想象,每当我们更改t-sql视图生成中包含的10+列的任何值时,sql都会通过生成的视图执行t-sql,因为它太重了。
我们知道运行一个简单的查询来重新计算值就足够了,这取决于我们改变的列值
但是sql如何理解呢?
答案 0 :(得分:2)
索引视图具体化,例如它包含的行(来自它所依赖的表)在磁盘上物理存储 - 就像“系统计算”表一样,只要其基础表发生变化,它就始终保持最新状态。这是通过添加聚簇索引来完成的 - 聚合索引的叶子页在SQL Server表(或视图)上 数据页,实际上。
索引视图中的列也可以使用非聚簇索引编制索引,因此您可以进一步提高查询性能。缺点是:由于存储了行,因此需要磁盘空间(显然有些数据是重复的)。
另一方面,普通视图只是SQL的一个片段,它将根据您从该视图中选择的内容来执行计算结果。该视图没有物理表示,没有为常规视图存储行 - 它们需要根据需要从基表连接在一起。
答案 1 :(得分:0)
为什么你认为关于索引视图中允许的内容有多么奇怪的规则,以及允许基表做什么?因此,SQL引擎可以立即知道“如果我触摸此行,它可能会影响此视图的结果 - 让我们看看,此行不再符合视图条件,但我坚持使用COUNT_BIG(*),所以我可以把这个值递减一个“