最新版MySQL与PostgreSQL是否会自动预编译所有执行的查询?
表述真实性验证
这个表述基本属实,但存在限定前提,不是所有场景都成立:
- sqlx底层依赖对应数据库的Go语言驱动,目前主流的PostgreSQL驱动
lib/pq、MySQL驱动go-sql-driver/mysql默认配置下,你直接调用DB.Query()、DB.Exec()这类方法执行查询时,驱动确实会在后台自动完成预编译、执行、销毁预编译句柄的全流程,这就是文档里描述的「自动预编译」 - 这种自动预编译生成的句柄是一次性的,执行完就会被释放,不会被缓存复用,和你手动调用
Prepare()生成的可复用句柄完全不同 - 如果你修改过驱动的默认配置,比如给MySQL驱动开启了
interpolateParams=true参数,驱动会直接在客户端把参数拼接进SQL语句再发给服务端,全程不会触发预编译,这种场景下文档的表述就不成立
日常开发是否需要手动预编译
完全看你的SQL使用场景:
- 推荐手动预编译的场景:
- 同一条结构固定的SQL会被高频多次执行:比如批量插入数据、接口每次被调用都会执行的固定查询逻辑,复用预编译句柄可以省掉每次执行的预编译开销,性能提升非常明显
- 对安全性要求极高的场景:预编译语句的SQL结构和参数是完全分离的,由数据库服务端解析,比客户端做参数转义的防注入效果更可靠
- 不需要手动预编译的场景:
- 单次执行、或者执行频率极低的SQL:比如后台管理端几天才调用一次的统计查询,手动预编译反而会长期占用数据库的预编译句柄资源,得不偿失
- 动态生成的SQL:每次执行的SQL结构都不一样,预编译后也没法复用,完全没必要做
小提示:手动预编译得到的
Stmt对象用完一定要调用Close()释放资源,不然会一直占用数据库端的预编译句柄,积累过多会导致数据库抛出句柄不足的错误。
内容的提问来源于stack exchange,提问作者ogbofjnr
相关产品推荐
相关产品推荐

