如何使用JDBC

时间:2019-03-29 08:38:20

标签: java postgresql jdbc vertica

我有一个JAVA应用程序,可以使用任何供应商的SQL数据库。现在,我们已经测试了Vertica和PostgreSQL。我想从数据库中的一个表中导出所有数据,然后稍后将其导入应用程序的另一个实例中。数据库的大小非常大,因此其中有很多行。导出和导入过程必须从Java代码内部完成。

到目前为止我们尝试过的是:

  • 导出:我们通过JDBC读取整个表(select * from),然后将其转储到具有所有所需INSERTS的SQL文件中。
  • 导入:包含这数千个INSERTS的文件是通过JDBC在目标数据库中执行的。

这不是一个有效的过程。首先,select * from部分由于其大小而给我们带来了问题,其次,如果在Vertica(https://forum.vertica.com/discussion/235201/vjdbc-5065-error-too-many-ros-containers-exist-for-the-following-projections)中一次接一个地插入会产生很多问题

什么是更有效的方法?是否有任何工具可以帮助该过程,或者没有“优雅”的解决方案?

3 个答案:

答案 0 :(得分:1)

为什么不通过批处理(以提高性能)和分块(避免错误并提供检查点,以防止故障后从何处开始)一步一步地导出/导入。

在大多数情况下,数据库支持具有许多值的INSERT查询,例如:

INSERT INTO table_a (col_a, col_b, ...) VALUES
(val_a, val_b, ...),
(val_a, val_b, ...),
(val_a, val_b, ...),
...

在单个这样的INSERT语句中生成的行数就是您的块大小,这可能需要针对特定​​的目标数据库进行调整(足够大以加快处理速度,但又足够小以使块不超过某些数据库限制并创建失败)。

如已经提出的,然后应在事务中执行每个块,并且您的应用程序应记住,以防万一发生错误,该块最后一次成功执行,因此可以继续 在下一次运行那里。

对于块本身,您确实应该使用LIMIT OFFSET

这样,您可以随时重复任何块,每个块本身都是原子的,它的性能要比单行语句好得多。

答案 1 :(得分:0)

我只能谈论PostgreSQL。

如果您通过在语句上调用值大于0(也许为10000)的SELECT来使用服务器端游标,则setFetchSize的大小不是问题。

如果{p> 1,{

  1. 您可以一次完成所有操作

  2. 您将INSERTS的{​​{1}}

答案 2 :(得分:0)

每个插入Vertica的文件都进入WOS(内存),并且周期性地将来自WOS的数据移到ROS(磁盘)中并放入单个容器中。每个节点每个投影只能有1024个ROS容器。对于Vertica而言,一次执行数千个INSERT绝不是一个好主意。最好的方法是将所有数据复制到文件中,然后使用COPY命令将该文件批量加载到Vertica。

这将为文件内容创建一个ROS容器。取决于要复制多少行,它会快很多倍(有时甚至几百倍)。

https://www.vertica.com/docs/9.2.x/HTML/Content/Authoring/SQLReferenceManual/Statements/COPY/COPY.htm

https://www.vertica.com/docs/9.2.x/HTML/Content/Authoring/ConnectingToVertica/ClientJDBC/UsingCOPYLOCALWithJDBC.htm