2012-05-03 72 views
4

我有什么:PostgreSql中的十亿行:分区还是不分区?

  • 简单服务器与一个至强8个逻辑核心,16 GB的RAM,2×7200转驱动器的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”表。

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

+0

头正常化,尾巴你不✔ –

+1

根据你想要用这些数据做什么,你可能会在硬件上有点动力不足 - 尤其是磁盘阵列。你需要仔细调整和设计你的工作流程才有机会。不要误解我的观点,我们在PostgreSQL数据库中拥有5TB数据的机器,每天都会有数千万的请求出现,而且性能非常出色,但我们并没有运行在一对7200 RPM的驱动器上。 – kgrittn

回答

10

如果要在大多数查询中使用选择条件,允许规划人员大部分时间跳过对大部分分区的访问,或者要定期清除分配给所有行的所有行,则分区是最有用的一个分区,或两者。 (删除表格是删除大量行的非常快速的方法!)我听说有人触及了一个门槛,分区帮助保持索引更浅,从而提高性能;但是真的可以回到第一点,因为您将索引树的第一层有效地移动到另一个地方 - 它仍然必须发生。

就它而言,听起来不像分区会有帮助。另一方面,标准化可能会提高性能,超出您的预期;通过保持所有这些行更窄,您可以将更多这些行放入每个页面,从而减少整体磁盘访问。我会做适当的第三范式正常化,并且只会偏离基于它会有所帮助的证据。如果在数据的第二个副本仍有磁盘空间的情况下出现性能问题,请尝试创建非规格化表并查看性能与规范化版本的对比情况。

+0

非常感谢您的回答! –

1

我认为这是有道理的,这取决于你的用例。我不知道你的30B行历史记录有多远,但是如果你的交易数据库不需要超过你决定的几个分区,那么划分是有意义的。

例如,如果您每次只查询两个月的数据值,按月分区非常合理。一年中的其他十个月可以移入报告仓库,使交易存储空间更小。

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

获取性能基准,进行分区并重新检查性能影响。

+0

我在我的文章中写道:“所有时期的数据都将被使用。”。这里我的意思是,没有查询将有日期过滤器。这就是为什么我问这里,是否有意义的分区。 –

0

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

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

  • 你的表应该被分区以便并行化查询;
  • HW应该能够在N个并行流中传送请求的IO数量。

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

正如其他人提到的那样,DBA在分区表中有更多好处,所以我个人会对任何预计每间隔会接收5M以上的行的表进行分区,无论是日,周还是月。

+0

这里的主要问题 - 如果我不使用分区修剪,并且我不会删除旧数据 - 我是否会从分区中获得任何好处,例如,按日期(以预测行的传播)? 一百个小表/索引会比一个大表/索引执行得更好吗?在什么情况下? –

+0

对于分区表的DBA维护更容易,因为所有操作都可以按每个分区完成,因此对系统和其他查询的影响较小。对于ORACLE,即使我们预计性能不会提高,我们也会划分所有大型表。尽管现在我们已经通过分析查询,在所有情况下设法找到了一个很好的分区键。我建议你进行一些测试以获得更好的照片。 – vyegorov

+1

这个问题特别关于PostgreSQL,而在PostgreSQL中,分区在大多数情况下并不会*简化DBA的操作。目前还没有一种声明式的分区方式;它通过继承机制以相当手动的方式实现。在PostgreSQL中进行分区不允许查询的执行被并行化 - 至少由计划者来执行;我想你可以建立多个连接,并用单独的查询查询每个分区的数据,并在完成所有结果后以某种方式将所有结果集中在一起,但在两个似乎不太可能取胜的驱动器上。 – kgrittn