6

我有的:

  • 具有 8 个逻辑内核、16 GB 内存、2 个 7200rpm 驱动器的 mdadm raid1 的简单服务器。
  • PostgreSql
  • 有很多数据可以处理。每天导入多达 3000 万行。
  • 时间 - 复杂查询最多可以执行一个小时

表的简化模式,这将非常大:

id| integer | not null default nextval('table_id_seq'::regclass)
url_id      | integer | not null
domain_id   | integer | not null
position    | integer | not null

上述模式的问题是我没有关于如何对其进行分区的确切答案。将使用所有时期的数据(没有查询将有日期过滤器)。

我考虑过在“domain_id”字段上进行分区,但问题是很难预测每个分区会有多少行。

我的主要问题是:

如果我不使用分区修剪并且我不打算删除旧数据,那么分区数据是否有意义?

那会有什么优点/缺点?

如果我不进行分区,将如何降低我的导入速度?

另一个与标准化有关的问题:

应该将 url 导出到另一个表吗?

标准化的优点

  • 表将包含平均大小为 20-30 字节的行。
  • “url_id”上的连接应该比“url”字段快得多

非规范化的优点

  • 可以更快地导入数据,因为我不必在每次插入之前查找“url”表。

任何人都可以给我任何建议吗?谢谢!

4

3 回答 3

12

如果您要在大多数查询中使用选择标准以允许规划器在大多数情况下跳过对大多数分区的访问,或者如果您要定期清除分配给分区的所有行,则分区是最有用的,或者两个都。(删除表是删除大量行的一种非常快速的方法!)我听说有人达到了一个阈值,分区有助于保持索引更浅,从而提高性能;但实际上这又回到了第一点,因为您有效地将索引树的第一级移动到另一个地方——它仍然必须发生。

从表面上看,分区听起来并没有帮助。

另一方面,规范化可能比您预期的更能提高性能。通过保持所有这些行更窄,您可以将更多的行放入每个页面,从而减少整体磁盘访问。我会做适当的第 3 范式规范化,并且仅根据它会有所帮助的证据来偏离。如果您在仍有磁盘空间用于数据的第二个副本时发现性能问题,请尝试创建非规范化表并查看与规范化版本相比性能如何。

于 2012-05-03T15:00:23.877 回答
1

我认为这是有道理的,具体取决于您的用例。我不知道您的 30B 行历史记录可以追溯到多长时间,但是如果您的事务数据库不需要的分区超过您决定的几个分区,那么分区是有意义的。

例如,如果您一次只查询两个月的数据,则按月分区非常有意义。一年中的其他十个月可以移动到报告仓库中,从而使交易存储空间更小。

您可以在分区中使用的字段受到限制。你必须小心那些。

获取性能基线,进行分区并重新测量以检查性能影响。

于 2012-05-03T13:41:45.057 回答
0

考虑到给定的数据量,您将主要等待 IO。如果可能,请使用不同的硬件配置执行一些测试,以尝试为您的方案获得最佳 IO 数据。恕我直言,一段时间后 2 个磁盘将不够用,除非幕后还有其他事情。

你的桌子每天都会以已知的比例增长。而且很可能每天都会被查询。由于您没有提到要清除的数据(如果,则对它进行分区),这意味着查询每天都会运行得更慢。在某个时间点,您将开始研究如何优化您的查询。其中一种可能性是在应用程序级别上并行化查询。但是这里应该满足一些条件:

  • 您的表应该被分区以并行化查询;
  • 硬件应该能够在 N 个并行流中提供请求数量的 IO。

所有答案都应通过不同设置的性能测试给出。

正如其他人所提到的,分区表中的 DBA 有更多好处,所以我个人会去分区任何预计每个间隔接收超过 5M 行的表,无论是一天、一周还是一个月。

于 2012-05-03T15:20:20.937 回答