海量 postgres 表的最佳实践
Best practice for massive postgres tables
我有一个 table,其中包含 3 个字段(用户名、target_value、分数),由用户名 (~400,000) 和 target_value (~4000) 的完整交叉在外部生成) 和计算得分,导致总行数约为 16 亿。
我对这个 table 的所有查询都将采用
的格式
SELECT *
FROM _table
WHERE target_values IN (123, 456)
我的初始版本包括 target_values 上的 BTREE 索引,但我最终花了 45 分钟对索引进行 BITMAP HEAP SCAN。
我也一直在研究 BRIN 索引、分区和 table 集群,但由于将每种方法应用于 table 需要数小时,我无法完全强制每个选项并测试性能。
在 Postgres 10 中处理具有非常 'blocky' 数据的单个海量 table 有哪些建议?
如果 table 是两个数据集的交叉连接,为什么不存储单独的 table 并根据需要计算连接?数据库擅长于此。
根据您的描述,如果您在 table 上 运行 CLUSTER
以索引顺序物理重写它,我希望能提高性能。那么你将不得不访问更少的 table 个块。
不幸的是 CLUSTER
会花费很长时间,使 table 不可用并且必须定期重复。
另一种可能更好的方法是将 table 按 target_value
划分。 4000个partition有点多,可以用list partitioning,把几个分区打包成一个partition。
这将允许您的查询仅在几个分区上执行快速顺序扫描。它还将使 autovacuum 的工作更容易。
然而,最重要的是,如果您 select 来自 table 的很多行,它总是需要很长时间。
我有一个 table,其中包含 3 个字段(用户名、target_value、分数),由用户名 (~400,000) 和 target_value (~4000) 的完整交叉在外部生成) 和计算得分,导致总行数约为 16 亿。
我对这个 table 的所有查询都将采用
的格式SELECT *
FROM _table
WHERE target_values IN (123, 456)
我的初始版本包括 target_values 上的 BTREE 索引,但我最终花了 45 分钟对索引进行 BITMAP HEAP SCAN。 我也一直在研究 BRIN 索引、分区和 table 集群,但由于将每种方法应用于 table 需要数小时,我无法完全强制每个选项并测试性能。
在 Postgres 10 中处理具有非常 'blocky' 数据的单个海量 table 有哪些建议?
如果 table 是两个数据集的交叉连接,为什么不存储单独的 table 并根据需要计算连接?数据库擅长于此。
根据您的描述,如果您在 table 上 运行 CLUSTER
以索引顺序物理重写它,我希望能提高性能。那么你将不得不访问更少的 table 个块。
不幸的是 CLUSTER
会花费很长时间,使 table 不可用并且必须定期重复。
另一种可能更好的方法是将 table 按 target_value
划分。 4000个partition有点多,可以用list partitioning,把几个分区打包成一个partition。
这将允许您的查询仅在几个分区上执行快速顺序扫描。它还将使 autovacuum 的工作更容易。
然而,最重要的是,如果您 select 来自 table 的很多行,它总是需要很长时间。