我有一个JAVA应用程序,可以使用任何供应商的SQL数据库。现在,我们已经测试了Vertica和PostgreSQL。我想从数据库中的一个表中导出所有数据,然后稍后将其导入应用程序的另一个实例中。数据库的大小非常大,因此其中有很多行。导出和导入过程必须从Java代码内部完成。
到目前为止我们尝试过的是:
select * from
),然后将其转储到具有所有所需INSERTS的SQL文件中。这不是一个有效的过程。首先,select * from
部分由于其大小而给我们带来了问题,其次,如果在Vertica(https://forum.vertica.com/discussion/235201/vjdbc-5065-error-too-many-ros-containers-exist-for-the-following-projections)中一次接一个地插入会产生很多问题
什么是更有效的方法?是否有任何工具可以帮助该过程,或者没有“优雅”的解决方案?
答案 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,{
您可以一次完成所有操作
您将INSERTS
的{{1}}
答案 2 :(得分:0)
每个插入Vertica的文件都进入WOS(内存),并且周期性地将来自WOS的数据移到ROS(磁盘)中并放入单个容器中。每个节点每个投影只能有1024个ROS容器。对于Vertica而言,一次执行数千个INSERT绝不是一个好主意。最好的方法是将所有数据复制到文件中,然后使用COPY
命令将该文件批量加载到Vertica。
这将为文件内容创建一个ROS容器。取决于要复制多少行,它会快很多倍(有时甚至几百倍)。