首页 > 解决方案 > 带有 BLOB 列的 MySQL 5.7 批量插入

问题描述

我正在尝试使用批量插入 MySQL

INSERT INTO TABLE (a, b, c) VALUES (?, ?, ?), (?, ?, ?)

我有常规登录,并且看到这在大多数情况下都非常有效。但是,当表有 BLOB 列时,它就不能正常工作了。

我正在尝试插入 20 条记录。

如果没有 BLOB,我会在通用日志中看到同一查询中的所有 20 条记录,同一查询中插入了 20 条记录。

有了 BLOB,我在常规日志中只看到每个查询 2 条记录,总共需要 10 个查询。

这是 MySQL、JDBC 驱动程序的问题,还是我遗漏了其他东西。我更喜欢使用 BLOB,因为我在 protobufs 中有数据。

这是一个示例表...

CREATE TABLE my_table (
  id CHAR(36) NOT NULL,
  name VARCHAR(256) NOT NULL,
  data BLOB NOT NULL,
  PRIMARY KEY (id)
);

然后,在代码中创建批量插入...

val ps = conn.prepareStatement(
  "INSERT INTO my_table(id, name, data) VALUES (?, ?, ?)")
records.grouped(1000).foreach { group =>
  group.foreach { r =>
    ps.setString(1, UUID.randomUUID.toString)
    ps.setString(2, r.name)
    ps.setBlob(3, new MariaDbBlob(r.data))
    ps.addBatch()
  }
  ps.executeBatch()
}

如果您运行它并检查常规日志,您将看到...

“2018-10-12T18:37:55.714825Z 4 查询 INSERT INTO my_table(id, name, fqdn, data) VALUES ('b4955537-2450-48c4-9953-e27f3a0fc583', '17-apply-test', _binary' 17 -apply-test\"AAAA(?2Pending8???,J$b4955537-2450-48c4-9953-e27f3a0fc583

1:2:3:4:5:6:7:8Rsystem'), ('480e470c-6d85-4bbc-b718-21d9e80ac7f7', '18-apply-test', _binary' 18-apply-test\"AAAA( ?2Pending8?????,J$480e470c-6d85-4bbc-b718-21d9e80ac7f7

1:2:3:4:5:6:7:8Rsystem') 2018-10-12T18:37:55.715489Z 4 查询 INSERT INTO my_table(id, name, data) VALUES ('7571a651-0e0b-4e78-bff0- 1394070735ce', '19-apply-test', _binary' 19-apply-test\"AAAA(?2Pending8?????,J$7571a651-0e0b-4e78-bff0-1394070735ce

1:2:3:4:5:6:7:8Rsystem'), ('f77ebe28-73d2-4f6b-8fd5-284f0ec2c3f0', '20-apply-test', _binary' 20-apply-test\"AAAA( ?2Pending8?????,J$f77ebe28-73d2-4f6b-8fd5-284f0ec2c3f0

如您所见,每个 INSERT INTO 中只有 2 条记录。

现在,如果您data从架构中删除该字段并插入并重新运行,您将看到以下输出(10 条记录)...

“2018-10-12T19:04:24.406567Z 4 查询 INSERT INTO my_table(id, name) VALUES ('d323d21e-25ac-40d4-8cff-7ad12f83b8c0', '1-apply-test'), ('f20e37f2-35a4- 41e9-8458-de405a44f4d9', '2-apply-test'), ('498f4e96-4bf1-4d69-a6cb-f0e61575ebb4', '3-apply-test'), ('8bf7925d-8f01-494f-8f9f-c5b8c742beae' , '4-apply-test'), ('5ea663e7-d9bc-4c9f-a9a2-edbedf3e5415', '5-apply-test'), ('48f535c8-44e6-4f10-9af9-1562081538e5', '6-apply-测试'), ('fbf2661f-3a23-4317-ab1f-96978b39fffe', '7-apply-test'), ('3d781e25-3f30-48fd-b22b-91f0db8ba401', '8-apply-test'), (' 55ffa950-c941-44dc-a233-ebecfd4413cf', '9-apply-test'), ('6edc6e25-6e70-42b9-8473-6ab68d065d44', '10-apply-test')"

所有 10 条记录都在同一个查询中

标签: mysqljdbcinsertmariadb

解决方案


我一直在修补,直到找到解决方法...

val ps = conn.prepareStatement(
  "INSERT INTO my_table(id, name, data) VALUES (?, ?, ?)")
records.grouped(1000).foreach { group =>
  group.foreach { r =>
  ps.setString(1, UUID.randomUUID.toString)
  ps.setString(2, r.name)
  //ps.setBlob(3, new MariaDbBlob(r.data))
  ps.setBytes(r.data)
  ps.addBatch()
}
ps.executeBatch()

使用PreparedStatement.setBytes而不是使用MariaDbBlob似乎可以解决问题


推荐阅读