PostgreSQL 数据库中同时向相同表执行缓慢写入操作

5
我猜这个问题更适合Database Administrators网站,如果是的话,请告诉我,我会将其移动。 :)
我是一个数据库/Postgres初学者,希望得到帮助。我已经设置了一个系统,可以并行处理10个任务,并将这些任务的输出写入同一个Postgres数据库中的相同表格。写入操作进行得很好,但是它们需要非常长的时间。我的日志文件显示我有30,000个任务的结果,但只有7,000个任务的结果被反映在数据库中。
我怀疑Postgres因某种原因排队等待写入,我的猜测是这是因为该表格具有自动增量主键。如果我尝试同时向同一张表格写入10条记录,我会认为它们必须排队等待,否则如何设置主键呢?
我的理解正确吗?还是我的数据库配置严重出错?我的系统管理员通常不做数据库方面的工作,如果您有任何调整建议,即使是基本的建议,我也很乐意听取。 :)

2
自增量并不总是必须排队的,关键在于它们不必是连续的或严格顺序的,因此系统可以为尚未完全写入的行“保留”一个键。在Postgres中,它们被实现为一个称为Sequence的单独对象,与表本身涉及的锁和事务分开。 - IMSoP
你能提供更多关于写入的信息吗?它们是使用INSERT ... VALUES进行简单的单记录插入,还是批量数据,或者来自其他查询的结果?而且,是否只有一个独立的表,还是正在检查或更新依赖项? - IMSoP
它们是使用INSERT...VALUES进行的简单单记录插入。没有依赖关系,虽然它们需要来自另一个查询的结果,但这些结果已经存储在内存中,并且只是被迭代访问。嗯 :/ - dmn
表格有多少个索引?有任何触发器吗?硬件怎么样?如果您要插入30,000条记录,最好做批量插入而不是单个的“INSERT”语句(虽然速度会慢些,但不应该很慢)。这里需要更多信息... - Clockwork-Muse
当然可以。这个表只有一个索引,即主键。我已经设置了一个规则来确保我们不会插入已经存在的记录。硬件方面,我们使用了gluster/NFS设置,但是数据库存储在专用服务器上。我认为批量插入应该会有所帮助。谢谢 :) - dmn
哦,抱歉,还有另一张表上的外键依赖关系... - dmn
1个回答

7
我怀疑Postgres因某种原因将写操作排队,我的猜测是这是由于该表具有自增主键引起的。如果我尝试同时向同一张表写入10条记录,我会认为它们必须被排队,否则主键怎么设置呢?
不是这样的。
如果您阅读序列文档,您会发现它们免除了事务可见性和回滚,特别是出于这个原因。使用nextval生成的ID在回滚时不会被重新使用。
我理解正确吗?还是我的数据库配置严重出错了?我的系统管理员通常不处理数据库,所以如果您有任何调整建议,即使是基本的建议,我也很乐意听取。 :)
更可能的是,您正在单个磁盘驱动器上进行单个提交,每次插入一个提交,并且该系统的fsync()非常慢。您可能还将检查点间隔设置得太低(如果是这样,则PostgreSQL日志中将出现有关此问题的警告),可能有太多的索引导致减速等等。
你应该查看PostgreSQL日志。
此外,请查看我撰写的有关提高插入性能的入门指南

哇,这太棒了。现在我有一个完整的清单可以尝试并让我的系统管理员试试。:D 非常感谢!让我们看看这会怎样。 - dmn
你知道什么对我真正有帮助吗?就是更少地提交代码。我使用 psycopg2 Python 模块,它将语句执行与提交分离开来。看起来并不重要我执行了多少个 insert,只有一次性在最后提交,那我就胜利了!:D - dmn
@dmn 听起来你所在的系统的 fsync() 速度相当慢,也许是磁盘硬盘没有 BBU 和写回缓存的 RAID 控制器的原因。 - Craig Ringer
是的,很有可能。我会去烦系统管理员的。>:D 另一个比最后提交更有帮助的事情是使用COPY。之前需要600秒的INSERT操作现在只需要1秒!再次感谢您的帮助和提供大量有用的信息。:D - dmn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接