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

Dee*_*pak 89 sql-server database-design indexed-views

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

mar*_*c_s 129

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

基本上,您需要做的就是:

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

你完成了!

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

其他资源:

  • 在视图上放置聚簇索引的限制很广泛.例如,视图不能引用其他视图,也不能包含外连接.因此,许多需要更好性能的视图无法使用此方法.还是一个很好的答案. (3认同)
  • 正如在相关问题中提到的,MSDN 博客文章 https://blogs.msdn.microsoft.com/ssma/2011/06/20/migrating-oracle-materialized-view-to-sql-server/ 强调了一些物化视图和索引视图之间的主要区别。恕我直言,最大的问题是无法指定刷新触发器:只要更新基表,索引视图就会更新 - 破坏了使用物化视图的大部分性能优势。对连接、聚合、窗口函数和子查询的禁止使得索引视图几乎毫无意义,除非数据不经常更改。 (3认同)

Raj*_*jiv 37

虽然纯粹从工程角度来看,索引视图听起来像每个人都可以用来提高性能,但现实生活场景却截然不同.我一直没有成功使用索引视图,因为对可索引的内容和不可索引的内容有太多限制.

如果视图中有外连接,则无法使用它们.此外,不允许使用公用表表达式...事实上,如果您在子选择或派生表中有任何排序(例如使用partition by子句),那么您也不幸.

只留下非常简单的场景来利用索引视图,我认为可以通过在底层表上创建适当的索引来优化.

我会很高兴听到一些真人生活场景,人们实际上已经使用索引视图来实现他们的利益,如果没有它们就无法做到

  • 您需要记住向使用索引视图的查询添加`(NOEXPAND)` 提示。然后你会注意到差异。使用索引视图与“正确索引表”的优点在于限制记录选择,否则您是正确的,它会是一样的。 (5认同)
  • 是的,NOEXPAND 的事情不能被低估! (3认同)

小智 18

您可能需要更多关于物化视图实际上是什么的背景知识.在Oracle中,当您尝试在其他地方构建它时,这些对象包含许多元素.

MVIEW本质上是来自其他来源的数据的快照.与视图不同,查询视图时找不到数据,它以表格的形式存储在本地.使用后台程序刷新MVIEW,后台程序定期启动或源数据发生变化时启动.Oracle允许完全或部分刷新.

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

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

其他一切都是实验.

  • OP索引的内容很容易通过索引视图提供.这是SQL Server本身为Oracle物化视图提供的最接近的东西.但是,如果您希望/需要完全复制Oracle MVIEW的工作方式,Jason是对的.Jason的方法也有助于Oracle MVIEWs的相同场景 - 例如,在报告表中进行非工作时间刷新,您更关心数据库负载而不是视图的最新状态(例如仅报告昨天的数字......) (10认同)
  • 您对SQL Server的评论不正确 - 物化视图在Oracle和SQL Server中是非常不同的.在SQL Server中,具有唯一聚簇索引的视图(也称为"物化视图")不会也不能由用户更新,也不会存储在单独的用户创建的表中 - 它始终由更新期间引擎,永远不会失去同步.存储数据的快照不需要任何工作. (4认同)

sto*_*tox 5

当索引视图不是一个选项,并且不需要快速更新时,您可以创建一个 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...
Run Code Online (Sandbox Code Playgroud)

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

每天/每晚/每周/诸如此类的刷新

begin transaction
truncate table cachetablename
insert into cachetablename select * from viewname
commit transaction
Run Code Online (Sandbox Code Playgroud)

注意:这会占用空间,也在您的 tx 日志中。最适用于计算缓慢的小型数据集。也许重构以首先将“简单但大”的列消除到外部视图中。