V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
rizon
V2EX  ›  程序员

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

  •  
  •   rizon ·
    othorizon · 2019-08-19 19:52:21 +08:00 via iPhone · 3336 次点击
    这是一个创建于 1674 天前的主题,其中的信息可能已经有所发展或是发生改变。
    java 使用 mybatis
    表是动态生成的。数据也是动态插入的。因此字段数量,每个字段的数据都是动态的。
    那么问题来了,当字段或每个字段的 value 值过长时,就会导致 sql 过长,无法写入数据。

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

    我能想到的方案就是计算字段与字段值的长度,然后动态地设置分批写数据时每个批次的大小
    第 1 条附言  ·  2019-08-22 00:35:16 +08:00
    问题 已经解决了,写了个方法,按照字节大小来分批插入,而不是按照条数来分批。
    第 2 条附言  ·  2019-08-22 00:36:21 +08:00
    问题 已经解决了,写了个方法,按照字节大小来分批插入,而不是按照条数来分批。
    字节大小则是根据‘ max_allowed_packet ’来配置的。
    感谢 v 友们的帮助
    12 条回复    2019-08-20 14:06:31 +08:00
    rizon
        1
    rizon  
    OP
       2019-08-19 20:03:30 +08:00 via iPhone
    问题 2,当 mysql 使用最大字段数量,每个字段使用最大长度的字符串作为值,那么插入一条数据时会超过 sql 长度吗?
    sandrew1945
        2
    sandrew1945  
       2019-08-19 20:06:06 +08:00
    试试预编译
    519718366
        4
    519718366  
       2019-08-19 21:13:58 +08:00
    字段过长导致插入失败,这是设计上的坑啊,要么加大长度,要么代码里截断。你代码里正常写就行,每个公司的监控系统就监控这种异常情况的。
    比如爬虫数据落库,你数据库 title 是 varchar(1024) 结果哪天就爬了个 2000 长度的标题,那插入肯定就挂了,这时候我肯定是代码里做截断,毕竟这种数据是少数。

    整个 sql 怕超长,就用 batch 模式吧,一般情况下 <foreach>就顶用了
    rizon
        5
    rizon  
    OP
       2019-08-19 23:29:10 +08:00 via iPhone
    @sandrew1945
    @519718366
    你们没明白,如果字段数量非常多,每个字段的值本就非常长。那么分批分几条数据的一批是要看每条数据的长度的。
    甚至可能出现一条数据的长度就已经超过了 sql 的长度了
    jugelizi
        6
    jugelizi  
       2019-08-19 23:34:52 +08:00
    黑人问号???
    这个时候难道不是要改 packet size
    340244120w
        7
    340244120w  
       2019-08-20 01:22:11 +08:00 via iPhone
    max allowed packet???
    aprilwei
        8
    aprilwei  
       2019-08-20 01:26:59 +08:00 via Android
    取消自动提交,batch 缓存
    lihongjie0209
        9
    lihongjie0209  
       2019-08-20 08:52:12 +08:00
    sql 还有长度一说??? 应该是 max allowed packet 吧
    msg7086
        10
    msg7086  
       2019-08-20 08:53:03 +08:00 via Android
    不改设置改代码,是吃得很饱么…
    Aresxue
        11
    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
        12
    leafin  
       2019-08-20 14:06:31 +08:00
    我教你,
    max_allowed_packet=1G
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3199 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 14:02 · PVG 22:02 · LAX 07:02 · JFK 10:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.