如何针对Java应用程序中的大量批量插入优化MySQL?

时间:2017-07-18 16:20:30

标签: java mysql optimization batch-processing

我在Windows 7 Pro 64位上运行了一些测试 它有一个i7-6700和8GB的内存 我从SSD访问文件并通过Java控制台应用程序处理它们,该应用程序将它们转换并加载到同一台机器上的mySQL服务器上,但是在一个单独的机械硬盘上。

我已禁用网页归档
我已将 innodb_buffer_pool_size 设置为 8M 设置为 2G
我已将 innodb_thread_concurrency 设置为 17 设置为 32
我已将 innodb_buffer_pool_instances 设置为 8 设置为 16
我已将 max_connections 设置为 151 设置为 256
无论出于何种原因,高于此值的任何内容都会导致服务器在启动时崩溃。我已经检查了安装并且MySQL报告说它是AMD64安装,但是我遇到的内存限制让我想知道它是否真的是32位安装。

我特别关注这个对象,结构如下 CustomObject1
字符串custObj1str1
字符串custObj1str2
字符串custObj1str3
字符串custObj1str4
int custObj1int1
int custObj1int2
float [7] custObj1fltArr1
float [7] custObj1fltArr2
ArrayList custObj2

CustomObject2
int custObj2int1
float [4] custObj2fltArr1

我从custObj1str1,custObj1str2,custObj1str3,custObj1str4,custObj1int1,custObj1int2为custObj1创建了一个HashKey,并将其用作主键。该对象分为4个单独的表。

table1
int hashkey(主键)
varchar custObj1str1
varchar custObj1str2
varchar custObj1str3
varchar custObj1str4
int custObj1int1
int custObj1int2

table2
int hashkey(主键)
float custObj1fltArr1 [0] ... float custObj1fltArr1 [6]

table3
int hashkey(主键)
float custObj1fltArr2 [0] ... float custObj1fltArr2 [6]

table4
int hashkey(主键,第1页)
int custObj2int1(主键,第2页)
float custObj1fltArr2 [0] ... float custObj2fltArr1 [4]

在Java中,我正在使用批处理来编写准备好的SQL语句 对于table1 - > " INSERT INTO table1 VALUES(?,?,?,?,?,?,?,?)ON DUPLICATE KEY UPDATE" + primaryKey +" =" + primaryKey
对于table4 - > " INSERT INTO table4 VALUES(?,?,?,?,?,?)ON DUPLICATE KEY UPDATE" + primaryKey +" =" + primaryKey +" AND" + foreignKey +" =" + foreignKey
我相信,对于table4,它会导致一些数据被覆盖,因为它有如此多的数据(超过30M的记录)。

这只是为期一天的数据,我可能需要管理4年。

Image of Table Status (sensitive info redacted)
任何建议将不胜感激。


**更新**

我尝试在MacBook Pro上使用mySQL(2013年末使用i7,16GB RAM和SSD)。它很慢,但仍然比Windows机器快得多。

MacBook Metrics
我将批量上载的方法设置为Synchronous,以限制导入同一个表的数据量。我应该在每个数据库的基础上限制它,保持原样,或完全删除它?我使用了8个计数线程池,但我想增加它。

1 个答案:

答案 0 :(得分:0)

那个Data_length可疑地接近2 ^ 31。 mysql驻留在什么文件系统上? NTFS应该没问题,但我怀疑FAT16和FAT32有局限性。 (数据库的增长速度比Windoz增长得快。)

让我们看看日志。并且32位将解释崩溃(它将在日志中)。如果是32位,则退回你提到的4个更改,但是innodb_buffer_pool_size = 1500M。即使64位并崩溃,看看这是否有帮助。

要判断批量插入,请提供SHOW CREATE TABLE以及您一次批处理的行数。

操作系统限制?

首先升级到64位MySQL。如果这还不够......

查看涉及的文件系统,看看是否有解决方法。其他...

如果问题是操作系统对文件大小的限制,那么可能是通过MySQL的解决方法。

  • ibdata1实际上可以是一组文件,您可以将每个文件限制为1GB。请参阅手册。如果你找不到它,我会把它挖出来。

  • 一个表可以是PARTITIONed,这样每个分区都足够小,以适应操作系统限制。这需要innodb_file_per_table=ON并仔细设计如何进行分区。在进一步建议之前,我需要看SHOW CREATE TABLE并了解每列中的值。

  • 5.7允许指定放置每个分区的位置 - 如果整个驱动器有限制,这将非常方便。 (与每个文件相对。)