【发布时间】:2020-02-04 16:09:13
【问题描述】:
我有两个表 T1 和 T2,它们类似于 PostgreSQL 数据库中更宽的表 T 的垂直分区。
我想通过在每个表上使用表扫描操作来低成本地连接这些分区,类似于将行成对组合到新行的类似 MERGE-JOIN 的操作。我的方法会假设表可以按扫描顺序合并连接,而不需要排序或检查任何连接谓词。主要目标是避免使用一些行标识符进行显式连接,这些行标识符也需要复制到所有分区中,这似乎是 PG 中垂直分区的常见模式。
表 T1 和 T2 没有索引并且是严格只读的。因此,优化器将找不到以不同顺序访问它们的替代方法。并行查询被禁用以避免并行扫描操作。
[过时的 Q1) 鉴于这些预防措施,PG 中是否有任何保证始终按插入顺序返回行,例如吸尘后? ]
Q2) 是否可以编写一个实现类似 MERGE-JOIN 的操作的 UDF,即类似于:
SELECT T1.*, func('T2') FROM T1;
或
SELECT * FROM func('T1', 'T2');
似乎归结为为 PG 编写一个用户定义的连接运算符。
更多想法:我的理解是 PL/pgSQL 函数将结果累积在 RETURN NEXT 和 RETURN QUERY 中,如果 T 有很多行,这可能会很昂贵。不确定游标是否有类似的开销。所以我真的不知道从哪里开始寻找。
编辑: 问了两个问题,我犯了一个错误。请忽略第一个关于保证的内容。 - 我知道没有这样的保证,我只是好奇究竟是什么导致 PostgreSQL 出现问题,因为我不熟悉那个系统。
为了澄清用例:我打算将数据放入外部只读文件中,例如CSV,可通过外部表访问,我可以完全控制扫描顺序。将其视为一些数据存档。
问:是否可以在 PostgreSQL 中编写一个用户定义的函数来处理一个游标(示例 1)或两个游标(示例 2)以及由服务器端的两次顺序扫描发出的“拼接”行?
【问题讨论】:
-
如果您使用内置的声明性分区,Postgres 12 会自动为您执行此操作(“partition wise join”)
-
"在 PG 中是否有任何保证,行总是按插入顺序返回" - 一个明确的 NO(不仅适用于 Postgres,但对于所有关系数据库)。保证结果顺序的唯一方法是使用
ORDER BY,别无选择。 -
感谢指向分区连接的指针。但据我了解,这都是关于水平分区的,例如按范围?
标签: postgresql user-defined-functions