【问题标题】:How to get high performance under a large transaction (postgresql)如何在大事务下获得高性能(postgresql)
【发布时间】:2012-07-04 03:22:43
【问题描述】:

我有 200 万条数据需要插入到 postgresql 中。但它发挥了低效。我可以通过将大事务拆分为较小的事务来实现高性能插入器(实际上,我不想这样做)?或者,还有其他明智的解决方案吗?

【问题讨论】:

  • 在不知道问题根源的情况下,很难解决问题。幸运一击:您尝试 COPY 插入数据吗?
  • “低性能”是什么意思?除非您在触发器上运行一些代码,否则在非常普通的 SSD 硬件上正常工作的 postgres 应该能够每秒插入大约 50k-200k 行。

标签: postgresql transactions


【解决方案1】:

不,让它更快的主要想法是在一个事务中完成所有插入。多个事务,或不使用事务,速度要慢得多。

并尝试使用复制,这样更快:http://www.postgresql.org/docs/9.1/static/sql-copy.html

如果你真的必须使用插入,你也可以尝试删除该表上的所有索引,并在加载数据后创建它们。

这也很有趣:http://www.postgresql.org/docs/9.1/static/populate.html

【讨论】:

  • 非常感谢,您知道为什么all in one transaction 比multiple-smallers 运行得更快吗?我渴望理论。 :)
  • " 如果您允许单独提交每个插入,PostgreSQL 会为添加的每一行做大量工作。" postgresql.org/docs/9.1/static/populate.html
  • 大量 INSERT 的性能也可以通过使用单个插入插入多行来提高(或例如在 JDBC 中使用批处理语句)
  • 谢谢,但我的意思不是为每个插入分配事务。例如,需要插入200万条记录,我将在一个事务中插入10000条记录,因此它将打开20个事务而不是一个。它会获得更高的性能吗?
【解决方案2】:

提高性能的可能方法:

  1. 使用COPY 命令。
  2. 如果您的数据可以处理后果,请尝试减少事务的isolation level
  3. 调整 PostgreSQL 服务器配置。默认内存限制非常低,即使服务器拥有千兆字节的可用内存,也会导致磁盘垃圾。
  4. 关闭 PostgreSQL 服务器上的磁盘屏障(例如,ext4 文件系统的nobarrier 标志)和/或fsync警告:这通常是不安全的,但会大大提高您的性能。
  5. 在插入数据之前删除表中的所有索引。在添加行时,一些索引需要大量工作才能保持最新。 PostgreSQL 最终可能能够更快地创建索引,而不是与插入过程并行地不断更新索引。不幸的是,没有简单的方法可以“保存”当前索引,然后再次恢复/创建相同的索引。

仅当由于并行事务的数据依赖性问题而必须重试事务时,将插入作业拆分为一系列较小的事务才会有所帮助。如果事务在第一次尝试时成功,将其拆分为多个依次运行的较小事务只会降低您的性能。

【讨论】:

    【解决方案3】:

    根据我的经验,您可以通过将大型事务拆分为较小的事务来提高 INSERT 完成时间,但前提是您要插入的表没有应用索引或约束,并且没有必须竞争的默认字段值对于多个并发事务下的共享资源。在这种情况下,将插入分成几个不同的部分,并将每个部分作为单独的进程同时提交,将在更短的时间内完成工作。

    【讨论】:

      猜你喜欢
      • 2011-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-25
      • 2016-06-06
      • 2017-02-15
      • 2018-10-19
      相关资源
      最近更新 更多