我正在设计一个具有数十万行的小型商业智能应用程序。我的大多数用户查询都依赖于另一个查询中的数据,该数据永远不会改变,但是会占用大量时间。因此,理想情况下,每天晚上我在数据库中重新加载数据时,都希望运行一次查询并将数据存储在中间表的某个位置。这是最佳做法吗? TEMP TABLE是在Postgres中执行此操作的最佳方法吗?由于这为Web应用程序提供服务,并且由于临时表在会话结束时到期,因此我想Web应用程序的会话在用户之间持续存在,因此足以满足此要求,即我不希望查询运行一次对于每个应用程序用户。谢谢!
答案 0 :(得分:1)
我们有一个存储过程,该存储过程将在某天首次登录我们的应用程序时启动,以刷新某些表中的数据。您可以执行类似的操作或在特定时间运行作业以删除并重新加载所有数据。
答案 1 :(得分:1)
使用实例化视图: https://www.postgresql.org/docs/9.3/static/sql-creatematerializedview.html
create materialized view mv_t1 as select a, b, (a+b) as absum from table_name;
Postgres MV与进行
基本相同create table t1 as select * from t2;
因为它们是“哑巴”,必须完全刷新。您可以将cronjob设置为每天或每小时运行一次以刷新它们。 Oracle的MV更为智能,可以根据更新和插入自动重新填充某些行。
refresh materialized view mv_t1;
如果您希望在刷新过程中可以访问MV,则可以执行以下操作:
refresh materialized view concurrently mv_t1;
请注意,要使用并发刷新功能,MV中的至少一列必须具有唯一约束(这是Postgresql跟踪已刷新的行的方式)。通常,这只是一个id
列。
为MV加上前缀可能是有帮助的,因为对于那些不了解其目的的开发人员而言,它们似乎只是普通表。我使用mv_
。
如果父表的架构发生更改,那么如果您希望它反映这些更改,则必须重新创建MV。 如果您不是手动创建MV(通过ORM或其他间接方法创建),请注意,在创建时会填充数据,这可能需要很多时间,具体取决于查询的复杂性。如果要创建仅具有结构的实例化视图,并在以后手动“刷新”它,则可以执行以下操作:
create materialized view m1 as select * from t1 with no data