jpm*_*c26 5 postgresql performance
我有一个表,其中包含一些基于其他表的预先计算的数据。(考虑到我必须处理的数据大小,动态计算的计算成本太高。)随着源数据的添加,我将逐步生成。(UPDATE在正常使用中我永远不需要它;部分可能会被删除和重新生成。)该表将相当大。它目前大约有 5000 万行,并且每年都会增长。
对该表的大多数查询都将通过外键 ID 列进行过滤。因此,如果该 ID 的所有行都分组到相同的页面中,它们的性能会更好。我可以通过创建索引和CLUSTER定期调用来保证磁盘上的这种排序,但这显然不太理想,因为它需要某种计划任务,根据使用情况和其他计划任务进行协调等。
但是,由于我以与我想要使用的外键相关的块的形式生成这些数据CLUSTER,因此我可以轻松地ORDER BY在INSERT命令中添加一个子句:
INSERT INTO big_table (source_table1_id,a,b,c)
SELECT
source_table1_id,
5 /* some formula */,
/* ... */
FROM source_table1
JOIN source_table2 ON ...
...
WHERE ... /* some condition indicating what needs to be generated */
ORDER BY source_table1_id
Run Code Online (Sandbox Code Playgroud)
这是否会影响磁盘存储顺序,将行分组为接近最小页数?如果确实如此,是否还有其他进程可能会在以后弄乱磁盘顺序?
我目前正在使用 PostgreSQL 9.3,但我想了解更新的版本以及升级。
Postgres 在物理上按 INSERTed 顺序写入元组。如果您对新表或没有死元组的表执行此操作,您将获得与CLUSTER在具有与INSERT. CLUSTER稍后以同样的方式写入表的效果会恶化(并且在您从不DELETE或UPDATE- 或INSERT破坏所需的顺序时保持完整)。
有些答案集中于后来的写作的影响,而忽略了问题的要点。你的问题的答案基本上是:
是的,按顺序插入确实与聚类具有相同的效果。
基于一些条件:
针对该表的查询将通过外键 ID 列进行过滤。
这意味着您可以一次访问具有相同 FK ID 的行,而不是一系列连续的 ID。那么您所需要的只是按 ID 聚集的行,ID 之间的物理顺序几乎对这些查询没有任何影响。
和:
生成与外键相关的数据块
意思是,“块”包括按顺序具有相同 FK ID 的所有行。没有单独插入同一 FK ID 的其他行。就像是:
INSERT INTO big_table (source_table1_id,a,b,c)
SELECT s1.source_table1_id, ...
FROM source_table1 s1
...
WHERE s1.source_table1_id BETWEEN 123 and 125 -- example
ORDER BY s1.source_table1_idRun Code Online (Sandbox Code Playgroud)
和:
UPDATE在正常使用中我不需要它;部分可以被删除并重新生成。
这DELETE是唯一有轻微问题的部分。如果您从不删除其中任何一个,那么您就完成了。ID如果您所说的“部分”是指同时表示的所有行,那么您仍然很好,大多数情况下。在同一事务中删除和插入时,ID 内不存在碎片。(已删除的元组尚未“死亡”,并且不会在同一事务中被覆盖。)
死元组会使表膨胀,随后的插入可以填充物理空洞,这就是碎片开始的地方。死元组造成的膨胀会产生各种累积的不利影响,但对具有相同 FK ID 的行的索引访问基本上不受影响。
但所有这些都与您的问题正交,因为同样的考虑因素也适用于CLUSTER.
考虑社区工具pg_repack或pg_squeeze。两者都可以替换CLUSTER,而不需要对表进行排它锁。看:
有关的:
| 归档时间: |
|
| 查看次数: |
787 次 |
| 最近记录: |