【问题标题】:How can I optimize MySQL for massive batch inserts from a Java application?如何优化 MySQL 以从 Java 应用程序进行大规模批量插入?
【发布时间】:2017-12-23 15:31:22
【问题描述】:

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

我已禁用页面归档
我已将 innodb_buffer_pool_size8M 设置为 2G
我已将 innodb_thread_concurrency17 设置为 32
我已将 innodb_buffer_pool_instances8 设置为 16
我已将 ma​​x_connections151 设置为 256
无论出于何种原因,任何高于此的值都会导致服务器在启动时崩溃。我检查了安装,MySQL 报告说它是 AMD64 安装,但我遇到的内存限制让我怀疑它是否真的是 32 位安装。

我对这个对象特别有问题,下面的结构
CustomObject1
字符串 custObj1str1
字符串 custObj1str2
字符串 custObj1str3
字符串 custObj1str4
int custObj1int1
int custObj1int2
浮动[7] custObj1fltArr1
浮动[7] custObj1fltArr2
ArrayList custObj2

CustomObject2
int custObj2int1
浮动[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(主键)
浮动 custObj1fltArr1[0] ... 浮动 custObj1fltArr1[6]

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

table4
int hashkey(主键,第 1 点)
int custObj2int1(主键,第 2 点)
浮动 custObj1fltArr2[0] ... 浮动 custObj2fltArr1[4]

在 Java 中,我正在使用批处理执行准备好的 SQL 语句
对于 table1 -> "INSERT INTO table1 VALUES (?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE " + primaryKey + " = " + primaryKey
For 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(2013 年末,配备 i7、16GB RAM 和 SSD)上使用 mySQL。它很慢,但仍然比 Windows 机器快得多。

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

【问题讨论】:

    标签: java mysql optimization batch-processing


    【解决方案1】:

    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 允许指定放置每个分区的位置——如果整个驱动器都有限制,这将很方便。 (相对于每个文件。)

    【讨论】:

    • 我的批量插入最大为 1K,直到所有记录都加载完毕。我之前登录错误的错误日志,(我移动了目录),它确实是一个32位系统。文件系统确实是 NTFS。
    • 我不认为 N​​TFS 停止在 2G,但我怀疑这是问题所在。也许将 MySQL 更新到 64 位会修复它,但我担心它可能不会。从第一天(或几乎如此)开始,MySQL(甚至是 32 位)已经处理了巨大的文件。但它总是受操作系统限制的摆布。
    • 我添加了更多选项。
    猜你喜欢
    • 2013-11-19
    • 1970-01-01
    • 1970-01-01
    • 2011-07-28
    • 2013-05-17
    • 2017-05-16
    • 2013-10-14
    • 2021-10-21
    相关资源
    最近更新 更多