我正在写一个程序,它对Postgres数据库进行了大量的写操作。在一个典型的场景中,我会将100,000行写到一个规范化良好的表中(三个外整键,它们的组合是表的主键和索引)。我正在使用PreparedStatements和executeBatch(),但是在我的笔记本电脑上,我只能设法在大约70秒内推入100k行,而我们要替换的嵌入式数据库(它具有相同的外键约束和索引)只需要10秒。
我是JDBC的新手,我不希望它能击败定制的嵌入式DB,但我希望它只慢2-3倍,而不是7倍。有什么明显的我可能遗漏的吗?写入的顺序重要吗?(例如,假设它不是索引的顺序?)为了获得更快的速度,需要看的东西?
发布于 2008-12-16 00:19:26
这是我在目前的项目中经常要处理的问题。对于我们的应用程序来说,插入速度是一个关键的瓶颈。然而,我们发现对于绝大多数数据库用户来说,选择速度是他们的主要瓶颈,所以你会发现有更多的资源来处理这个问题。
下面是我们提出的一些解决方案:
首先,所有的解决方案都涉及到使用postgres COPY command。到目前为止,使用COPY将数据导入postgres是最快的方法。但是,默认情况下,JDBC驱动程序当前不支持跨网络套接字进行复制。因此,如果您想使用它,您需要执行以下两种变通方法之一:
one.
要插入的数据和数据库位于同一物理计算机上,您可以将数据写出到文件系统上的文件中,然后使用COPY命令批量导入数据。
提高速度的其他选择是使用JNI来访问postgres api,这样您就可以讨论unix套接字,删除索引和pg_bulkload project。然而,最终如果你没有实现复制,你会发现你的性能总是令人失望。
发布于 2008-12-16 02:01:10
检查您的连接是否设置为autoCommit。如果autoCommit为true,那么当您调用executeBatch时,如果批处理中有100个项目,它将发出100个单独的提交。这可能比调用executingBatch()然后显式提交()要慢得多。
我会避免在插入过程中删除索引或外键的诱惑。当您的load正在运行时,它将表置于不可用状态,因为当索引消失时,没有人能够查询表。另外,这似乎是无害的,但是当您尝试重新启用约束,但由于发生了一些您意想不到的事情而失败时,您该怎么办?RDBMS具有完整性约束是有原因的,禁用它们甚至“一小段时间”都是危险的。
发布于 2008-12-15 16:05:19
显然,您可以尝试更改批处理的大小,以找到适合您的配置的最佳大小,但我怀疑您是否会获得第三个因子。
您还可以尝试调整您的数据库结构。使用单个字段作为主键可能比使用组合PK具有更好的性能。根据您需要的完整性级别,您可以通过取消激活数据库的完整性检查来节省相当多的时间。
您还可以更改正在使用的数据库。对于高速简单的插入来说,MySQL应该是相当好的……我知道有一个MySQL的分支,它试图削减功能,以在高并发访问上获得非常高的性能。
祝你好运!
https://stackoverflow.com/questions/368736
复制相似问题