如何在SQL Server中创建实例化视图?


101

我将设计DW,并且听说过物化视图。实际上,我想创建一个视图,并且在更改基本表时它应该自动更新。任何人都可以用查询示例进行解释。

Answers:


144

它们在SQL Server中称为索引视图 -阅读这些白皮书以了解更多背景信息:

基本上,您需要做的是:

  • 创建常规视图
  • 在该视图上创建聚簇索引

完成了!

棘手的部分是:视图必须满足许多约束和限制-白皮书中概述了这些约束和限制。如果您这样做-这就是全部。该视图将自动更新,无需维护。

其他资源:


感谢您的回复。我得到了我想要的。我也想了解索引。我想知道在准备好所有表结构后,是否可以在SQL Server中生成星型架构图?如果是,我如何为此创建事实表?
迪帕克

3
在视图上放置聚簇索引的限制很广泛。例如,该视图不能引用其他视图,并且不能包含外部联接。因此,许多需要更好性能的视图无法使用此方法。仍然是一个很好的答案。
杰夫·威尔逊

1
正如一个相关问题中提到的那样,MSDN博客文章blogs.msdn.microsoft.com/ssma/2011/06/20/…突出显示了物化视图和索引视图之间的一些关键区别。最具问题的恕我直言,不能指定刷新触发器:只要更新基表,索引视图就会更新-削弱了使用物化视图的大多数性能优势。除非数据不经常更改,否则对连接,聚合,窗口函数和子查询的禁止使索引视图几乎毫无意义。
Suncat2000 '18

43

虽然纯粹从工程角度来看,索引视图听起来像是每个人都可以用来提高性能的东西,但现实生活中的情况却大不相同。我一直无法在最需要它们的地方使用索引视图,因为对可以索引和不能索引的内容有太多限制。

如果视图中有外部联接,则无法使用它们。另外,不允许使用公用表表达式...实际上,如果您在子选择表或派生表中有任何顺序(例如,使用partition by子句),那么您也很不走运。

这仅使非常简单的场景可以利用索引视图,我认为可以通过在基础表上始终创建适当的索引来优化某些内容。

我会很高兴听到一些现实生活中的场景,在这些场景中,人们实际上已经使用索引视图来受益,而没有索引视图就无法做到


实际上,我已经使用索引视图(仅一次)对全文搜索索引进行了分区。FTS索引确实不能分区,但是可以在同一表的多个视图上创建单独的索引。不过,这是最后的选择。
areyesram

4
您需要记住向(NOEXPAND)使用索引视图的查询添加提示。然后您会注意到差异。使用索引视图与“正确索引表”相比,其优势在于限制了记录的选择,否则您是正确的,它是相同的。
ajeh

是的,NOEXPAND的东西不能被低估!
Simon_Weaver

18

您可能需要更多有关物化视图实际内容的背景。在Oracle中,当您尝试在其他位置构建对象时,这些对象由许多元素组成。

MVIEW本质上是另一个来源的数据快照。与视图不同,在查询视图时找不到数据,该数据以表格形式存储在本地。MVIEW使用后台程序刷新,该程序定期启动或在源数据更改时启动。Oracle允许全部或部分刷新。

在SQL Server中,我将使用以下内容创建一个基本的MVIEW以定期(完整)刷新。

首先,一个视图。对于大多数人来说,这应该很容易,因为视图在任何数据库中都很常见。这应该与列和数据中的视图相同。这将存储视图数据的快照。然后,一个过程将截断该表,并根据视图中的当前数据重新加载该表。最后,一个触发程序开始工作的工作。

其他一切都是实验。


5
您对SQL Server的评论不正确-物化视图在Oracle和SQL Server中是完全不同的事情。在SQL Server中,具有唯一聚集索引的视图(也称为“物化视图”)不会,也不能由用户更新,也不会存储在单独的用户创建的表中-始终由用户更新引擎在更新过程中,并且永远不会不同步。无需执行任何操作来存储数据快照。
ErikE 2014年

10
OP所要求的内容可以通过索引视图轻松提供。这是SQL Server本机提供给Oracle实例化视图的最接近的内容。但是,如果您希望/需要完全复制Oracle MVIEW的工作方式,Jason是正确的。贾森(Jason)的方法还可以在相同的情况下提供帮助,例如在Oracle MVIEW可以非工作时间刷新报告表的情况下,您更关心数据库负载,而不是视图的最新状态(例如,仅报告昨天的数字...)

4

如果没有索引视图选项,并且不需要快速更新,则可以创建一个hack缓存表:

select * into cachetablename from myviewname
alter table cachetablename add primary key (columns)
-- OR alter table cachetablename add rid bigint identity primary key
create index...

然后使用sp_rename视图/表或更改引用它的任何查询或其他视图以指向高速缓存表。

安排每天/每晚/每周/什么都不会刷新

begin transaction
truncate table cachetablename
insert into cachetablename select * from viewname
commit transaction

注意:这会占用您的TX日志中的空间。最适用于计算速度较慢的小型数据集。也许重构是为了消除“容易但很大”的列,而这首先要进入外部视图。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.