背景
最近在将项目的数据库连接池从Spring自带的一个默认连接池切换到Alibaba的Druid。在做数据库连接参数优化时,对poolPreparedStatements应当如何配置产生了困惑。
探究
Druid的官方文档中的提示如下:
是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。
但是在百度搜索相关文章时,有些文章提到:
MySQL 5.7以前的确是不支持PSCache的,但是从MySQL5.7开始,官方支持游标,所以建议开启PSCache
这就很尴尬了,到底能不能开呢?
后来又找到了一篇文章《浅析 MySQL JDBC 连接配置上的两个误区》里面倾向于新版本的MySQL可以打开PSCache
由于项目使用的是阿里云的PolarDB数据库服务,所以我通过工单咨询了PolarDB工程师的意见(PolarDB虽然是阿里自研的云原生数据库,但是其MySQL8.0版100%兼容MySQL8.0)
最终得到的工单回复是:
- MySQL在Server端并没有真正意义上的Prepared Statement机制,也没有类似于Oracle的Hard parse/Soft parse/no Parse
- MySQL客户端的Prepared statement要解决的是,将SQL固化,并控制参数的传递,实际的价值在于避免“SQL 注入“,通过传参来携带对服务端有伤害的SQL语句;主要工作原理是,在应用层以标位符的形式来控制输入
结论
我们到底是否要开启MySQL的PSCache,我认为应当根据站点的实际情况而定
- MySQL5.7之前就不要开了
- Druid有个监控后台,打开后在数据库连接一栏可以看到PSCache的命中数据。如果命中率很好,那么对站点性能是有价值的,可以尝试。如果命中率很低,则不建议开启。毕竟PSCache是占用内存的(附Druid官方文档中关于如何配置监控后台)
- 根据阿里工程师的意见,项目中如果使用了MyBatis这样的组件,并且使用了#的值引入方式,则无需担心SQL注入问题。那么MySQL中Prepared statement的价值就不存在了。