Questions tagged «materialized-view»

物化视图的定义类似于视图,但拥有像表一样的持久数据,是包括Oracle,DB2和postgres在内的许多RDBMS的功能。SQL Server具有一个称为“索引视图”的相似功能,该功能被认为足以包含在此标记下。

7
编写一个简单的银行架构:如何使我的余额与他们的交易记录保持同步?
我正在为一个简单的银行数据库编写模式。基本规格如下: 数据库将针对用户和货币存储交易。 每个用户每种货币都有一个余额,因此每个余额只是针对给定用户和货币的所有交易的总和。 余额不能为负。 银行应用程序将专门通过存储过程与其数据库进行通信。 我希望该数据库每天可以接受成千上万的新交易,并且可以平衡更高数量级的查询。要非常快地用完余额,我需要预先对其进行汇总。同时,我需要保证余额永远不会与其交易历史相矛盾。 我的选择是: 有一个单独的balances表,然后执行下列操作之一: 将交易应用到transactions和balances表。TRANSACTION在存储过程层中使用逻辑,以确保余额和交易始终保持同步。(由Jack支持。) 将交易应用到transactions表格,并使用触发器balances为我更新交易金额。 将事务应用于balances表,并具有一个触发器,该触发器transactions为我在表中添加一个具有事务量的新条目。 我必须依靠基于安全性的方法来确保在存储过程之外无法进行任何更改。否则,例如,某些过程可能会直接将事务插入transactions表中,而根据计划1.3,相关余额将不同步。 有一个balances索引视图可以适当地汇总事务。存储引擎保证余额与事务保持同步,因此我不需要依靠基于安全性的方法来保证这一点。另一方面,由于视图-甚至是索引视图-都没有CHECK约束,因此我不能再将余额强制为非负数。(由Denny支持。) 仅具有一个transactions表,但具有一个附加列来存储该交易执行后立即生效的余额。因此,用户和货币的最新交易记录也包含其当前余额。(下面由安德鲁建议;由garik提出。) 当我第一次解决这个问题时,我阅读了这 两个讨论并决定选择2。作为参考,您可以在此处看到其基本实现。 您是否设计或管理了这样的具有高负载配置文件的数据库?您如何解决此问题? 您认为我做出了正确的设计选择吗?我有什么要记住的吗? 例如,我知道对transactions表的架构更改将需要我重建balances视图。即使我在归档事务以保持数据库较小(例如,通过将它们移动到其他地方并用汇总事务替换),每次架构更新都必须从数千万个事务中重建视图,这可能意味着每个部署的停机时间会大大增加。 如果要使用索引视图,如何保证没有余额是负数? 归档交易: 让我详细说明一下归档事务和上面提到的“摘要事务”。首先,在这样的高负载系统中,定期归档将是必要的。我想保持余额与交易记录之间的一致性,同时允许将旧交易移至其他位置。为此,我将使用每位用户和货币金额的摘要替换每一批已归档的交易。 因此,例如,以下交易清单: user_id currency_id amount is_summary ------------------------------------------------ 3 1 10.60 0 3 1 -55.00 0 3 1 -12.12 0 已归档并替换为: user_id currency_id amount is_summary ------------------------------------------------ 3 1 -56.52 1 …

1
如何在SQL Server 2017中使用SNAPSHOT_MATERIALIZATION创建视图?
SQL Server 2017有几个新的存储过程: sp_refresh_single_snapshot_view – @view_name nvarchar(261),@ rgCode int的输入参数 sp_refresh_snapshot_views – @rgCode int的输入参数 以及sys.messages中的新条目: 10149 –无法在视图'%。* ls'上创建具有SNAPSHOT_MATERIALIZATION的索引,因为视图定义包含内存优化表。 10642 –无法为'%。* ls'上的索引'%。* ls'设置SNAPSHOT_MATERIALIZATION,因为它仅适用于视图上的索引。 10643 –不能在'%。* ls'上为'%。* ls'设置SNAPSHOT_MATERIALIZATION,因为它仅适用于视图上的聚集索引。 10648 –无法为'%。* ls'上的分区索引'%。* ls'设置SNAPSHOT_MATERIALIZATION。 10649 –无法在具有SNAPSHOT_MATERIALIZATION的聚集索引'%。* ls'的'%。* ls'上创建非聚集索引'%。* ls'。 10650 –刷新快照视图要求在数据库上启用快照隔离。 3760 –无法在具有SNAPSHOT_MATERIALIZATION的视图'%。* ls'上删除索引'%。* ls'。 4524 –无法更改视图'%。* ls',因为它具有快照实现。 4525 –刷新视图之前,无法在具有快照实现的视图'%。* ls'上使用提示'%ls'。 以及新的扩展事件: 那么我们如何创建快照实现的视图呢?(显然,Microsoft尚未对此进行记录。)这是我迄今为止尝试过但仍未奏效的要点。

2
在PostgreSQL中增量刷新子视图
是否可以在PostgreSQL中增量刷新实例化视图,即仅刷新新数据或已更改的数据? 考虑此表和实例化视图: CREATE TABLE graph ( xaxis integer NOT NULL, value integer NOT NULL, ); CREATE MATERIALIZED VIEW graph_avg AS SELECT xaxis, AVG(value) FROM graph GROUP BY xaxis 定期将新值添加到graph或更新现有值。我只想graph_avg每两个小时刷新一次已更新值的视图。但是在PostgreSQL 9.3中,整个表都被刷新了。这非常耗时。下一版本9.4允许CONCURRENT更新,但仍刷新整个视图。对于亿万行,这需要几分钟。 跟踪更新和新值并仅部分刷新视图的好方法是什么?

2
将索引视图用于聚合-太好了以至于无法实现?
我们有一个数据仓库,它的记录数很大(10-20百万行),并且经常运行查询来对某些日期之间的记录进行计数,或者对带有某些标志的记录进行计数,例如 SELECT f.IsFoo, COUNT(*) AS WidgetCount FROM Widgets AS w JOIN Flags AS f ON f.FlagId = w.FlagId WHERE w.Date >= @startDate GROUP BY f.IsFoo 性能并不是很糟糕,但可能会相对缓慢(在冷缓存中可能为10秒)。 最近,我发现我可以GROUP BY在索引视图中使用,因此尝试了类似于以下内容的操作 CREATE VIEW TestView WITH SCHEMABINDING AS SELECT Date, FlagId, COUNT_BIG(*) AS WidgetCount FROM Widgets GROUP BY Date, FlagId; GO CREATE UNIQUE CLUSTERED …

3
在Postgres中替换实例化视图
我有一个物化视图Postgres 9.3,我想用新的列进行更新。但是,其他实例化视图也依赖于此视图,并且错误消息表明,当其他对象依赖该视图时,则无法删除该视图。 错误:无法删除实例化视图latest_charges,因为其他对象依赖它 从文档中还可以看出,REPLACE关键字对于实例化视图无效。除了删除所有依赖对象并重建每个依赖对象之外,还有没有捷径可走?

3
在Postgres中查询实例化视图的定义
我想知道如何在Postgres中查询实例化视图的定义。作为参考,我希望执行的操作与常规视图的操作非常相似: SELECT * FROM information_schema.views WHERE table_name = 'some_view'; 它为您提供以下列: table_catalog table_schema table_name view_definition check_option is_updatable is_insertable_into is_trigger_updatable is_trigger_deletable is_trigger_insertable_into 物化视图可能吗? 到目前为止,从我的研究看来,物化视图似乎是故意从information_schema中排除的,因为 information_schema仅可以显示SQL标准中存在的对象。 (http://www.postgresql.org/message-id/3794.1412980686@sss.pgh.pa.us) 由于它们似乎被完全排除在information_schema之外,因此我不确定该怎么做,但是我想做的事情有两个: 查询是否存在特定的实例化视图。(到目前为止,我发现这样做的唯一方法是尝试创建一个具有相同名称的垫视图,看看它是否爆炸了。) 然后查询实例化视图的定义(类似于上的view_definition列information_schema.views)。

1
选择索引视图的聚集索引有哪些因素?
简而言之 ,查询优化器选择索引视图索引时会考虑哪些因素? 对我来说,索引视图似乎无视我对Optimizer如何选择索引的理解。我以前看过这个问题,但是OP不太受欢迎。 我确实在寻找路标,但是我将伪造一个伪示例,然后发布带有大量DDL,输出和示例的真实示例。 假设我使用的是Enterprise 2008+,请理解 with(noexpand) 伪示例 以这个伪示例为例:我创建一个具有22个联接,17个过滤器和一个马戏团小马的视图,该马戏小马穿过一千万个行表。这种观点很昂贵(是的,用大写字母E)可以实现。我将对SCHEMABIND进行索引并为视图建立索引。然后一个 SELECT a,b FROM AnIndexedView WHERE theClusterKeyField < 84。在Optimizer逻辑中,我无法进行底层联接。 结果: 没有提示:4825读取720行,在76ms内读取47 cpu,估计的子树开销为0.30523。 使用提示:17次读取,720行,4 ms内15 cpu,估计的子树成本为0.007253 那么这是怎么回事?我已经在Enterprise 2008、2008-R2和2012中进行了尝试。通过每一个度量标准,我都认为使用视图索引的效率大大提高。我没有参数嗅探问题或数据偏斜,因为这是广告问题。 一个真实(长)的例子 除非您是一个受虐狂,否则您可能不需要或不想阅读此部分。 是的 ,企业版。 Microsoft SQL Server 2012-11.0.2100.60(X64)2012年2月10日19:39:15版权所有(c)Windows NT 6.2(Build 9200:)上的Microsoft Corporation Enterprise Edition(64位)(Hypervisor) 风景 CREATE VIEW dbo.TimelineMaterialized WITH SCHEMABINDING AS SELECT TM.TimelineID, TM.TimelineTypeID, TM.EmployeeID, …


1
解决仅通过索引视图相关的2个表的死锁
我遇到了陷入僵局的情况,我想我已经缩小了罪魁祸首的位置,但是我不确定该如何解决。 这是在运行SQL Server 2008 R2的生产环境中。 为了让您对情况略有简化: 我有3个表,定义如下: TABLE activity ( id, -- PK ... ) TABLE member_activity ( member_id, -- PK col 1 activity_id, -- PK col 2 ... ) TABLE follow ( id, -- PK follower_id, member_id, ... ) 该member_activity表具有定义为的复合主键member_id, activity_id,因为我只需要以这种方式在该表上查找数据。 我也有一个非聚集索引follow: CREATE NONCLUSTERED INDEX [IX_follow_member_id_includes] ON follow ( …


2
DBCC CHECKDB无法修复的损坏:索引视图包含视图定义未生成的行
TL; DR:我在索引视图中有无法修复的损坏。详细信息如下: 跑步 DBCC CHECKDB([DbName]) WITH EXTENDED_LOGICAL_CHECKS, DATA_PURITY, NO_INFOMSGS, ALL_ERRORMSGS 在我的一个数据库上产生以下错误: 消息8907,级别16,状态1,第1行空间索引,XML索引或索引视图“ ViewName”(对象ID 784109934)包含视图定义未生成的行。这不一定表示此数据库中数据的完整性问题。(...) CHECKDB在表'ViewName'中发现0个分配错误和1个一致性错误。 repair_rebuild是最低修复级别(...)。 我确实知道,该消息表明索引视图“ ViewName”的物化数据与基础查询生成的数据不同。但是,手动验证数据不会出现任何差异: SELECT * FROM ViewName WITH (NOEXPAND) EXCEPT SELECT ... from T1 WITH (FORCESCAN) join T2 on ... SELECT ... from T1 WITH (FORCESCAN) join T2 on ... EXCEPT SELECT * FROM ViewName …

3
如果两个过程尝试同时同时刷新材料视图,会发生什么?
根据文档: 同步刷新实例化视图,而不会锁定实例化视图上的并发选择。(...) ...其他内容... 即使使用此选项,一次也只能针对任何 一个实例化视图运行一次REFRESH。 我有一个功能,可以检查上次刷新时间以进行材料视图,如果超过60秒,它将刷新它。 但是,如果我尝试同时从两个单独的进程中刷新实例化视图,将会发生什么?他们会排队还是会引发错误? 有没有一种方法可以检测何时刷新了材料视图,因此避免触摸它? 目前,我在刷新之前将表记录填充(设置refreshing为true),然后false在过程完成时将其设置为。 EXECUTE 'INSERT INTO refresh_status (last_update, refreshing) VALUES (clock_timestamp(), true) RETURNING id') INTO refresh_id; EXECUTE 'REFRESH MATERIALIZED VIEW CONCURRENTLY my_mat_view'; EXECUTE 'UPDATE refresh_status SET refreshing=false WHERE id=$1' USING refresh_id; 然后,每当我调用此过程时,我都会检查最新过程last_update及其refreshing值。如果refreshing为true,则不要尝试刷新实例化视图。 EXECUTE 'SELECT extract(epoch FROM now() - (last_update))::integer, refreshing FROM refresh_status ORDER BY …

2
改用ARITHABORT ON的风险
我正在与一家供应商合作,安排他们提供核心应用程序,只要不修改核心应用程序,我就可以构建自己的扩展。它内置在ColdFusion中,可连接到SQL Server 2005数据库。 我构建的某些报告依赖于使用从核心表计算出的函数的视图,并且随着表的增大,报告变得非常慢。为了加快报告速度,我想使用索引视图。但是,在我的测试环境中创建了索引视图之后,核心应用程序无法再插入到核心表中(它返回了一条错误消息,这ARITHABORT是ON使用索引视图时所必需的)。 因此,似乎为了使用索引视图,SET ARITHABORT ON每当插入/更新核心表时,我都需要拥有核心应用程序。我在测试环境中运行了此命令: ALTER DATABASE MyDatabase SET ARITHABORT ON; 而且似乎工作正常。但是我的供应商说,由于应用程序具有成千上万的查询,因此该设置可能会中断其中一个查询,并且如果将来出现一些意外的数据库问题,他们会坚持要求我恢复默认设置。 是否有实际的查询会被打破SET ARITHABORT ON?在任何情况下都最好保留它OFF? TL; DR为了使新的索引视图生效,我需要ARITHABORT ON为整个数据库进行设置,但是我的供应商警告说,这将由我自己承担风险。实际上有风险吗?

2
为什么索引视图不允许非唯一聚集索引?
我一直在研究使用索引视图来提高一些我们最常用的视图的性能。 但是,索引视图不支持非唯一的聚集索引,这与其余数据库结构设置的优先级略有不同。 例如,这是几个表的简化版本。 -Groups- Group ID GroupName -Users- UserKey UserName FullName GroupID 索引位于Groups.GroupID(非群集)和Users.GroupID(群集)上。聚簇键位于“用户”表中的GroupID上,因为通常会检索到来自特定组的一系列用户。显然,每个组将有多个用户,因此该聚集索引是唯一的。 这使我不确定如何在索引我的视图(例如本示例)时遵循此优先顺序,因为我无法拥有非唯一的聚集索引。 ConsumableID ConsumableVariantID AllowThresholdOverwrite FullPath GroupID ManufacturerID Type ModelID 101 29 1 0.1.2.4. 4 3 3 2 实际上,此View上唯一唯一的值是ConsumableID列,因此在将索引放置到什么地方时,我别无选择。 为什么在常规表允许时View不允许非唯一聚集索引?

2
SQL Server中的索引视图
我有一张桌子和它的索引视图 Create table mytable1 (ID int identity(1,1), Name nvarchar(100)) Create table mytable2 (ID int identity(1,1), Name nvarchar(100)) Create view myview with schemabinding as select a.name, b.name from mytable1 a join mytable2 b on a.Id = b.Id 现在,如果我运行以下查询 select a.name, b.name from mytable1 a join mytable2 b on a.Id = b.Id …

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.