mysql的中in的参数怎么预处理_mysql sql预处理之总结

根据自己有限的java数据库编程的经验,对sql做预处理可以提高执行的效率,所以对mysql的c API做了些探索。从好坏两方面来总结mysql提供的这些接口:

好处是,他提供的是一种buffer的机制,我对它做了优化,就是为所有的参数buffer数据创建了一个大的静态的或者全局缓冲区,这样每次改变buffer内容的时候只需要对相应的字段赋值即可,不需要每次重新设置buffer指向的内存,因为这块内存是不变的,参数字段名字和这个内存地址做一个map,赋值的时候可以直接查找到参数的地址。如果有多个prepare statement,且是一个线程内,这块数据缓存可以共同利用,互不干扰的。如果用的hash_map,效率很高,每次参数赋值的消耗是很少的,几乎等同于变量赋值的。

需要注意的是sql字段类型,buffer_type枚举,c ++数据类型之间的映射关系,必须保证不会内存越界。buffer_length可以不指定的,那样就会直接使用length了,当然这是update/insert,如果是select还是要有的。读了mysql的driver的源码才确定了在bind param的时候是如何赋值内存的,如果不是blob 或者buffer长度。在调试时,如果发现写到数据库的和程序中的值不一致,这是可能的问题根源。

我不确定prepare statement在执行时究竟是走的拼sql的流程还是有一个专门的二进制协议来只传递参数值,源代码中这段没找到。我测出来的是执行prepare statement和直接执行sql语句的效率基本上是一致的,有很小很小的提高。

因此,我确定,使用prepare statement的最大节省的是拼sql语句的消耗,如果拼的话往往要使用字符串流的机制,效率比较低,这部分的时间消耗等于执行sql的消耗。理想的情况,不适用prepare statement,弄一个sql语句,拼的时候在参数的地方预留缓冲区,然后赋值的时候就直接把值放到缓冲里,然后把sql直接执行就好了,难题在于变长的char*和blob的缓冲区如何分配,分配的一个足够大的缓冲,如果实际值不够长的话就填充空格。这个还在瞎想阶段,实现起来很难。

使用了prepare statement也省去了escape特殊字符的麻烦,提高了安全性。

问题在于我对一个prepare statement的各个参数每次用到的可能不同,这次用这个参数,不用另一个参数,这样prepare statement就不同了,只好重新建一个。如果有十几个字段,每次不确定用哪几个字段,这在只修改需要修改的内容时是必须的,为了减少不必要的存档生成,当然这个情景很特殊。。。却是我所面对的。如果能在param的buffer增加一个字段来表示这个字段是否有效就好了,可惜没有。

prepare statement需要长期占用数据库连接,这个对于有限的连接数也是一个问题,又、需要有一个类似于连接池的prepare statement池机制啊。。。

这就是我的总结了,具体代码网上搜一大堆。读了源代码收获比较大,它能让我完全确认它是如何工作的。

Great open source!

阅读(5292) | 评论(0) | 转发(0) |

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值