加速大量插入多个数据库
Speed up a massive number of inserts into multiple databases
我写了一个脚本,使用 MyBatis 执行大量插入 多个数据库 。之前的脚本没有使用 MyBatis,或多或少,两倍快(100 万条记录 25 分钟,使用 MyBatis 1 小时 10 分钟)。我尝试过不同的东西,但我不知道如何配置 MyBatis 来提高它的性能。关于我的问题和解决方案的一些具体考虑:
- 数据库位于 VPC 中,因此网络时间很重要。
- 我使用 guice 为每个数据库绑定映射器。连接信息以编程方式设置。当我需要执行插入时,映射器就会被获取。
- 需要插入的行没有排序,所以按数据库入队。当队列达到给定大小时,将执行 多行插入 。我可以更好地使用注入映射器吗?
- 我使用 池化 连接。这是否意味着在第一次使用mapper然后重新使用时打开了3个连接?如果给定的映射器仅每隔几分钟使用一次,那些空闲连接将被关闭?
有时我会随机得到这个错误:
org.apache.ibatis.transaction.TransactionException: Error configuring
AutoCommit. Your driver may not support getAutoCommit() or
setAutoCommit(). Requested setting: false.
Cause:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 4,030,088 milliseconds ago.
The last packet sent successfully to the server was 0 milliseconds ago.
如何提高性能并避免通信错误?
1、看来您需要更改连接池参数。
像mysql这样的数据库可能会在目标时间间隔内空闲时关闭连接,但是连接池可能不会被注意到,所以当你的映射器使用关闭的连接时,会发生 CommunicationsException。
(1)如果你使用c3p0,你可以指定idle_test_period来解决这个问题。
(2) 或者您可以指定 jdbc Timeout Settings(Max Wait Time、Idle Timeout)
2、连接池有minSize和maxSize 属性 ,当你的空闲连接数大于minSize时,超出部分将被关闭
我认为您必须优化 mysql 配置才能批量插入:enter link description here
看起来 mybatis 尝试将 autocommit 设置为 false,这是一个很好的优化。
而且我认为最好通过数据库拥有一个映射器实例并使用 guice 创建 3 个数据源。
另一种方法是使用 sqlimport 但这是一个很大的突破。
我写了一个脚本,使用 MyBatis 执行大量插入 多个数据库 。之前的脚本没有使用 MyBatis,或多或少,两倍快(100 万条记录 25 分钟,使用 MyBatis 1 小时 10 分钟)。我尝试过不同的东西,但我不知道如何配置 MyBatis 来提高它的性能。关于我的问题和解决方案的一些具体考虑:
- 数据库位于 VPC 中,因此网络时间很重要。
- 我使用 guice 为每个数据库绑定映射器。连接信息以编程方式设置。当我需要执行插入时,映射器就会被获取。
- 需要插入的行没有排序,所以按数据库入队。当队列达到给定大小时,将执行 多行插入 。我可以更好地使用注入映射器吗?
- 我使用 池化 连接。这是否意味着在第一次使用mapper然后重新使用时打开了3个连接?如果给定的映射器仅每隔几分钟使用一次,那些空闲连接将被关闭?
有时我会随机得到这个错误:
org.apache.ibatis.transaction.TransactionException: Error configuring AutoCommit. Your driver may not support getAutoCommit() or setAutoCommit(). Requested setting: false. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure The last packet successfully received from the server was 4,030,088 milliseconds ago. The last packet sent successfully to the server was 0 milliseconds ago.
如何提高性能并避免通信错误?
1、看来您需要更改连接池参数。
像mysql这样的数据库可能会在目标时间间隔内空闲时关闭连接,但是连接池可能不会被注意到,所以当你的映射器使用关闭的连接时,会发生 CommunicationsException。
(1)如果你使用c3p0,你可以指定idle_test_period来解决这个问题。
(2) 或者您可以指定 jdbc Timeout Settings(Max Wait Time、Idle Timeout)
2、连接池有minSize和maxSize 属性 ,当你的空闲连接数大于minSize时,超出部分将被关闭
我认为您必须优化 mysql 配置才能批量插入:enter link description here 看起来 mybatis 尝试将 autocommit 设置为 false,这是一个很好的优化。 而且我认为最好通过数据库拥有一个映射器实例并使用 guice 创建 3 个数据源。
另一种方法是使用 sqlimport 但这是一个很大的突破。