Sql “物化视图”的最佳方式
PostreSQL 8.2,在WindowsXP上运行 我有很多复杂的查询,每次运行都需要几秒钟。它们实际上不是视图,但可以这样处理 我决定将这些视图中的结果记录持久化到表中,我称之为辅助表 我可以保证在计算aux表后不会有数据更改 让我们举一个例子: 假设我有一个查询X,所以我将其结果保存在表X中。记录集如下所示:Sql “物化视图”的最佳方式,sql,postgresql,Sql,Postgresql,PostreSQL 8.2,在WindowsXP上运行 我有很多复杂的查询,每次运行都需要几秒钟。它们实际上不是视图,但可以这样处理 我决定将这些视图中的结果记录持久化到表中,我称之为辅助表 我可以保证在计算aux表后不会有数据更改 让我们举一个例子: 假设我有一个查询X,所以我将其结果保存在表X中。记录集如下所示: PERSON* FIELD_A* FIELD_ B FIELD_C ========================================
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
如您所见,每个人在该表中都有自己的记录子集
这样,我就可以很快地找到他的记录了
从表_x中选择*其中person=
我总是只通过获取,并且我所有的查询都有相同的面孔:PERSON+一些字段
重要提示:所有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,而且我只需要更新几条记录,所以我正在尝试一种有效的方法
我尝试以单独的步骤删除/更新/插入,直接从复杂的查询中执行,但这需要太多时间,因为查询执行了3次,一次用于删除,另一次用于更新,另一次用于插入
有什么建议吗?在执行此操作之前,您是否对复杂的查询运行了解释计划,并添加了索引以改进它
如果你必须这样做,忘记所有的循环废话;没有比数据库的内部C和汇编代码更优化的了。只需编写一个视图并在必要时将其具体化,方法是在表中选择*即可。在许多情况下,这将比循环、删除和插入更快。使用PostgreSQL构建自己的物化视图的两个标准参考是一致的,并且在您走这条路之前,尽可能快地进行查询。如果您必须使物化视图与当前数据保持同步,则物化视图可能会很快变得复杂。请参阅以获取一些好信息。