分区还是不分区?

Kam*_*ski 8 postgresql performance partitioning postgresql-9.4

已经阅读了关于 SO、外部博客文章和手册的几个问题

我仍然发现自己想知道是否应该考虑我的情况进行分区。

案例 - 简化

存储客户数据。为了清楚起见,下面提到的所有表的名称都是由组成的。

  1. 拥有可被客户识别且为非物理存在的对象,以及实际存储它们的物理对象,以备需要根据需要将某些对象发送回客户,或以其他方式对其进行处理。它们以多对多关系映射。objects_nonphysical, objects_physical, objects_mapping_table.

  2. 第二个多对多关系是那些非物理对象与其度量之间的关系。有些对象与某些指标绑定。metrics,metrics_objects_nonphysical

  3. 非物理对象和物理对象都有它们的层次表,它们是子父关系。objects_nonphysical_hierarchy,objects_physical_hierarchy

根据每个客户的需要和要求,可以提供或可能需要从头开始创建有关物理对象的数据。基本上,我需要做的是:

  • 维护快速INSERTSELECT语句的内部系统,因为这里是映射发生的地方。

  • 维护系统供外部客户查看和操作他们的非物理对象- 快速检索数据。对报表效率的强烈需求SELECT- 许多客户可以随时搜索这些数据。

我的考虑

可以有一个客户,他可以访问数据、查看数据并对其进行操作,但这不需要是我们从中获取数据/正在为其处理数据的承包商。

这促使我将表分区引入我的系统,考虑到我总是知道应该属于哪个分区数据(承包商分区),然后为外部客户维护系统,我需要为客户分区(这将通过一些延迟使用自动化工具和一组规则以客户方式重写数据,以便对于每个客户,我们只扫描每个表的一个分区。

数据量

我的数据将不断增长,尤其是在导入新客户的对象和指标时。从长远来看,目前新数据进入系统的速度是不可预测的。在不知道谁将成为下一个客户的情况下,真的没有办法衡量它。眼下正好有2客户提供更多或更少的1M行对每个表的每个客户。但在未来,我预测新客户的数量也会达到1000 万行左右。

问题

这些问题都是相互关联的。

  1. 真的应该在这里考虑分区,还是说这是一种矫枉过正?我认为它很有用,因为我总是只扫描一个分区。
  2. 如果分区是可行的方法,FK考虑到我的需求,我如何最有效地强制执行约束?我应该选择constraint triggers,还是将其保留在内部系统的应用程序层中,或者其他方法?
  3. 如果分区不是可行的方法,我应该深入研究什么?

如果没有提供足够的数据,请在下面的评论中告诉我。

Eze*_*nay 0

如果您现在实施分区,也不会造成什么影响,但在您的系统确实需要新分区之前,请使用单个分区。在性能方面,处理主键等只会有很小的开销。

我建议使用重定向插入的规则和主键的外部表(例如CREATE TABLE objects_physical_ids (id bigserial NOT NULL PRIMARY KEY),以及一个在 ids 表中插入一行并将其复制到 NEW.id 的函数触发器(例如INSERT INTO objects_physical_ids DEFAULT VALUES RETURNING id INTO NEW.id;),以及处理删除的其他触发器和更新,以及为每个继承表执行这些函数触发器的触发器(当您创建新的继承表时不要忘记执行此操作!)。然后所有相关表都可以具有FOREIGN KEY相关的 ids 表(包括任何外键操作,例如ON UPDATE或者ON DELETE)。

  • 规则和触发器肯定有开销,而且很容易衡量。此外,它们还增加了复杂性并使调试变得更加困难。另外,经过几次这种方式之后,我建议(虽然不知道所有细节)保留一个空的父表和一个或多个子分区。当更改分区方案时,这可能会非常方便。 (2认同)