Database design 每次查询PostgreSQL视图时,是否都是新创建的?

Database design 每次查询PostgreSQL视图时,是否都是新创建的?,database-design,postgresql,union,tableview,Database Design,Postgresql,Union,Tableview,我正在创建一个web应用程序,它有一些复杂的底层关联。为了解决几个问题,我创建了一个联合视图。可能还有很多其他方法可以解决这个问题 但我现在正在考虑我的设计的效率,我想知道视图是每次查询时新创建的,还是只创建一次并不断更新 更详细地说,如果我有表a(100条记录)和表b(100条记录)并创建联合视图,那么我创建了一个包含200条记录的视图 每次我对视图进行选择时,是否都会发生整个过程 同样,很明显,每次我更新基础表记录时,视图都会更新,但是视图是更新这一条记录还是从头开始重新创建整个视图 Dal

我正在创建一个web应用程序,它有一些复杂的底层关联。为了解决几个问题,我创建了一个联合视图。可能还有很多其他方法可以解决这个问题

但我现在正在考虑我的设计的效率,我想知道视图是每次查询时新创建的,还是只创建一次并不断更新

更详细地说,如果我有表a(100条记录)和表b(100条记录)并创建联合视图,那么我创建了一个包含200条记录的视图

每次我对视图进行选择时,是否都会发生整个过程

同样,很明显,每次我更新基础表记录时,视图都会更新,但是视图是更新这一条记录还是从头开始重新创建整个视图


Dale

视图只不过是一个带有名称的查询。可能存在一些与性能相关的优化,一些DBMS比其他DBMS实现得更好(pgSQL似乎更好),比如重用查询计划、缓存访问控制等

然而,在一天结束时,几乎总是可以预期视图的行为类似于直接发出SQL。不同的是,您可以授予对此查询的访问权,而不授予对基础表的访问权

您可以进行一些优化来更改行为(使其半表化),这些优化可能存在于类似pgSQL的物化视图中,也可能不存在于其中(很抱歉,不知道pgSQL),但这只是吹毛求疵

每次我对视图进行选择时,是否都会发生整个过程

是的。
非物化视图(PostgreSQL不支持物化视图)只是一个准备好的SQL语句——通过将视图引用替换为包含视图所基于的SELECT的子查询,可以获得相同的性能

这就是为什么每次在视图上运行查询时都会出现基于支持表的值的原因,我不清楚在PostgreSQL中是否会在不刷新视图的情况下显示列操作-即:如果基于SELECT*FROM table_x创建视图,然后从表_x中添加或删除列-大多数数据库都需要刷新视图以通过视图查看更改


不鼓励在视图之上构建视图-它们很脆弱;在运行依赖于另一个视图的视图之前,您不会知道是否存在问题。而且没有性能提升——相反。代码重用在基于集合的环境中不能很好地执行…

使用EXPLAIN查看视图是如何执行的,您将看到与普通查询相同的结果

EXPLAIN
SELECT * FROM name_of_your_view WHERE foo = 23;

PostgreSQL将尝试优化内部查询,即使在您连接视图、使用其他视图创建视图等情况下也是如此。请尽量避免在优化器完成其(出色)工作之前必须执行视图的情况。聚合、排序依据和限制是使用内部嵌套视图时可能出现的问题的示例。用EXPLAIN看看发生了什么。

谢谢你,弗兰克。试图用解释的方法,但我没有得到任何合理的答复。我现在明白了视图实际上只是一个查询语句。我现在想知道的是,-如果我对视图进行选择,查询是否首先查找所有行以创建视图,然后查找所有行以进行选择?或者它比这个更有效?这是我做的解释查询:解释选择*来自person\u角色,其中person\u id=3;结果是:排序(cost=2.95..2.97行=9宽度=42)排序键:public.links.created_at->HashAggregate(cost=2.71..2.80行=9宽度=42)->Append(cost=0.00..2.46行=9宽度=42)->链接上的顺序扫描(cost=0.00..1.19行=5宽度=42)过滤器:(origin id=3)->链接上的顺序扫描(cost=0.00..1.19行=4宽度=42)过滤器:(rcvd_id=3)PostgreSQL非常聪明,别担心。优化器检查查询中表的统计信息,检查可用索引和WHERE语句。优化器重写您的查询,然后神奇地找出哪个queryplan是最快的查询。在您的情况下,它使用顺序扫描,不使用任何索引。我猜数据量是非常有限的,但也可能是因为您在origin_id和rcvd_id列上没有索引。请检查如何工作。顺便说一句,
INSERT
一次只能影响一个表,因此如果您的视图在多个表上进行
连接
,您的
INSERT
只能列出其中一个表中的列。postgres从9.3开始就支持物化视图