PreparedStatement 比 Statement 更高效,因其预编译一次后可复用执行计划,避免重复硬解析;支持执行计划缓存、二进制参数传输及批量操作优化,实测快2–5倍。

PreparedStatement 比 Statement 更高效,核心在于它把“编译”和“执行”真正分开了——编译只做一次,执行可重复多次。而 Statement 每次都要从头解析、校验、优化、生成执行计划,开销大且不可复用。
预编译减少重复解析
数据库执行 SQL 前必须完成语法检查、语义验证、权限校验、统计信息收集、执行路径选择等步骤,这个过程叫“硬解析”,耗 CPU 和内存。PreparedStatement 在 prepareStatement() 阶段就把带 ? 占位符的 SQL 发送给数据库,完成一次硬解析并缓存执行计划;后续调用 executeQuery() 或 executeUpdate() 时,只传参数值,直接复用已编译好的计划。Statement 每次都拼出完整 SQL 字符串(如 "WHERE id = 123"),数据库视为全新语句,强制重新硬解析。
执行计划缓存命中率高
主流数据库(MySQL、Oracle、PostgreSQL)会对预编译语句的执行计划做缓存。只要 SQL 模板一致(如 "SELECT * FROM users WHERE status = ?"),不同参数(status = 'active' 或 status = 'pending')都能命中同一缓存项。Statement 的 SQL 字符串含具体值,哪怕只差一个数字,哈希值就不同,无法复用缓存。实测中,万级查询下 PreparedStatement 可比 Statement 快 2–5 倍。
网络与批量操作更轻量
PreparedStatement 使用二进制协议传输参数,只发数值本身(如 4 字节 int),不传整个 SQL 文本;Statement 必须把拼接好的字符串(含引号、转义、空格)全量发送,带宽占用高。批量操作时,PreparedStatement 的 addBatch() + executeBatch() 能复用同一个预编译句柄,仅批量提交参数组;Statement 批量需反复构造并发送多条完整 SQL,网络和解析压力成倍增加。
立即学习“Java免费学习笔记(深入)”;
驱动层还能进一步优化
像 MySQL JDBC 驱动支持 cachePrepStmts=true、prepStmtCacheSize=250 等配置,让客户端也缓存 PreparedStatement 对象,避免重复创建开销。这些优化对 Statement 完全无效——它没有“模板复用”的概念,每次都是新对象、新字符串、新请求。


















