(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另一次用于插入)
有什么建议吗?
答案 0 :(得分:5)
使用PostgreSQL构建自己的物化视图的两个标准参考是PostgreSQL/Materialized Views和Materialized Views That Really Work
答案 1 :(得分:2)
在您执行此操作之前,您是否对复杂查询运行了解释计划,并添加了索引以改进它?
如果你必须这样做,请忘记所有循环的垃圾;你所做的就是对数据库的内部C和汇编代码进行更优化。如果必须,只需编写一个视图并实现它,通过从中选择*到表中。在许多情况下,这将比循环,删除和插入更快。