Java mysql 动态 insert 一张表时,怎么防止 sql 语句过长

2019-08-19 19:52:21 +08:00
 rizon
java 使用 mybatis
表是动态生成的。数据也是动态插入的。因此字段数量,每个字段的数据都是动态的。
那么问题来了,当字段或每个字段的 value 值过长时,就会导致 sql 过长,无法写入数据。

这个东西有什么好的限制或解决方案吗?现成的工具最好。

我能想到的方案就是计算字段与字段值的长度,然后动态地设置分批写数据时每个批次的大小
3534 次点击
所在节点    程序员
12 条回复
rizon
2019-08-19 20:03:30 +08:00
问题 2,当 mysql 使用最大字段数量,每个字段使用最大长度的字符串作为值,那么插入一条数据时会超过 sql 长度吗?
sandrew1945
2019-08-19 20:06:06 +08:00
试试预编译
kingwrcy
2019-08-19 20:13:21 +08:00
mybatis foreach 手动控制长度,分批执行,guava 中有 Lists.partition
519718366
2019-08-19 21:13:58 +08:00
字段过长导致插入失败,这是设计上的坑啊,要么加大长度,要么代码里截断。你代码里正常写就行,每个公司的监控系统就监控这种异常情况的。
比如爬虫数据落库,你数据库 title 是 varchar(1024) 结果哪天就爬了个 2000 长度的标题,那插入肯定就挂了,这时候我肯定是代码里做截断,毕竟这种数据是少数。

整个 sql 怕超长,就用 batch 模式吧,一般情况下 <foreach>就顶用了
rizon
2019-08-19 23:29:10 +08:00
@sandrew1945
@519718366
你们没明白,如果字段数量非常多,每个字段的值本就非常长。那么分批分几条数据的一批是要看每条数据的长度的。
甚至可能出现一条数据的长度就已经超过了 sql 的长度了
jugelizi
2019-08-19 23:34:52 +08:00
黑人问号???
这个时候难道不是要改 packet size
340244120w
2019-08-20 01:22:11 +08:00
max allowed packet???
aprilwei
2019-08-20 01:26:59 +08:00
取消自动提交,batch 缓存
lihongjie0209
2019-08-20 08:52:12 +08:00
sql 还有长度一说??? 应该是 max allowed packet 吧
msg7086
2019-08-20 08:53:03 +08:00
不改设置改代码,是吃得很饱么…
Aresxue
2019-08-20 09:45:52 +08:00
sql 没有限制长度。而且这种批量代码你也是敢写,都超过内存最大限制了,说明一条 sql 里有太多条记录,max allowed packet 的本义就是让你拆分 sql,试想你 10w 里面有一条失败了,如果是 mysql 默认的严格模式你这 10w 条就都白插了。而且长时间 IO 可能给系统带来非常大的负荷,不谈死锁什么的,很有可能还会超时(jdbc 的超时时间, net_write_timeout 的超时时间, connect_timeout 的超时时间你都要考虑)。。。请想清楚你要干什么兄弟
leafin
2019-08-20 14:06:31 +08:00
我教你,
max_allowed_packet=1G

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/593289

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX