“物化视图”的最佳方式

时间:2009-08-02 04:27:51

标签: sql postgresql

(PostreSQL 8.2,在WindowsXP上运行)

我有很多复杂的查询,每个查询运行几秒钟。它们实际上不是“观点”,但可以这样对待。

我决定将那些“视图”中的结果记录保存到表中,我将其称为“辅助”表(。辅助)。

我可以保证在计算“aux”表后没有数据更改。

我们举一个例子:

我有一个查询“X”,所以我把它的结果保存在“Table_X”中。记录集是这样的:

PERSON*     FIELD_A*     FIELD_ B         FIELD_C
=======================================================
1           10           Value1           Value2
1           20           Value3           Value4
1           30           Value5           Value6
------------------------------------------------------
2           10           Value1           Value2
2           20           Value3           Value4
------------------------------------------------------
3           20           Value3           Value4
3           30           Value5           Value6
------------------------------------------------------
etc..

(*)Primary key is: person, field_a

如您所见,每个“人”在此表中都有他的记录子集。

所以,我可以快速获取他的记录 "select * from table_x where person = <person>"

我将始终只通过<person>抓取,并且我的所有查询都具有相同的“面孔”:“PERSON”+ Some_Fields。

重要提示:当我“重新填充”它们时,所有“aux”表都可以被其他事务处理(很明显,在我提交之前使用“旧”数据)。            但我可以保证他们永远不会被这些交易更新。

我目前的流程是:

- START TRANSACTION;
  - DO A LOTS OF OPERATIONS ON DATABASE. INSERT / UPDATE / DELETE ON SEVERAL TABLES.
  - AFTER THAT, I WILL CALCULATE "AUX" TABLES
  - LOOP THROUGH ALL MY "QUERIES": (WHERE HERE WE CAN CALL AS "X")
    - LOOP TROUGHT ALL "PERSON": (WHERE HERE WE CAN CALL AS <person>)
      - DELETE FROM <TABLE_X> WHERE PERSON = <person>; 
      - INSERT INTO <TABLE_X> (PERSON, FIELD_A, FIELD_B, FIELD_C)
                              (SELECT <person>, 
                                      FIELDS...
                                 FROM "LOTS OF TABLES" 
                                 JOIN "COMPLEX SQL"...
                                WHERE SOME_FIELD = <person>
                              );
    - END LOOP "PERSON"
  - END LOOP "QUERIES"
- COMMIT;

考虑:

其中一些表有数千条记录,如果与表中已经“存在”的记录集进行比较,通常只需要更新/删除/插入几条记录。

由于删除和“重新插入”导致过多的“磁盘i / o”(如此明显),我需要“更新”几条记录,我正在努力获得一种有效的方法

我尝试在separeted步骤中删除/更新/插入,直接从“复杂查询”执行,但需要花费太多时间,因为查询执行了3次(一次用于删除,另一次用于更新e另一次用于插入)

有什么建议吗?

2 个答案:

答案 0 :(得分:5)

使用PostgreSQL构建自己的物化视图的两个标准参考是PostgreSQL/Materialized ViewsMaterialized Views That Really Work

答案 1 :(得分:2)

在您执行此操作之前,您是否对复杂查询运行了解释计划,并添加了索引以改进它?

如果你必须这样做,请忘记所有循环的垃圾;你所做的就是对数据库的内部C和汇编代码进行更优化。如果必须,只需编写一个视图并实现它,通过从中选择*到表中。在许多情况下,这将比循环,删除和插入更快。