PreparedStatement&Batch

PreparedStatement

  • 使用占位符,一次解析多次执行,可提高性能
  • 可防止SQL注入
  • 可缓存的PS,可提高性能
  • 需要数据库服务端支持

Batch操作

  • 一次IO提交多条sql语句
  • 减少IO次数,提高性能

Mysql和Oracle是否使用预编译的思考

Mysql(mysql 5.7.20和mysql-connector-java-8.0.15.jar)

  • 基于同一连接,一次解析多次执行,jdbc driver实现可缓存PS
  • 以前的版本默认useServerPrepStmts=true,5.0.5以后的版本默认useServerPrepStmts=false mysql jdbc默认不开启PreparedStatement,收到的sql已经是替换成具体值的Sql.此时使用PS Batch 等同于普通的Sql Batch操作
  • useServerPrepStmts=true:服务端启用预编译机制,客户端(jdbc driver)只要不close掉statement,该statement可以多次重复使用,而不用再执行prepareStatement
  • cachePrepStmts=true:客户端(jdbc driver)close掉statement时,不会真的close,而是放connection缓存里。后续客户端只要不close掉connection,那么客户端即使再调用了prepareStatement,也是使用之前客户端缓存的客户端。有点类似PreparedStatementCache,但PSCache是从数据库连接池框架(druid的maxOpenPreparedStatements,BoneCP的statementsCacheSize,c3p0的maxStatementsPerConnection)层面上来讲,而此处指的是jdbc driver层面。
  • statement执行close方法时才会放入缓存,如果close之前,同样sql语句多次调用了prepareStatement方法,则会返回多个无关的statement,客户端在依次close掉这些statement时,只会缓存其中的一个statement,其它会被回收掉。这也证明mysql服务端不会做任何缓存或者唯一之类的处理,只会纯粹的做预编译处理,然后返回statement_id给客户端。
  • 一次编译多次执行,指的是数据库服务器端做一次预编译处理,客户端可以多次使用statement对象与服务器进行交互。
  • rewriteBatchedStatements=true:mysql自身实现的批量操作方法(转换成muti value的方式),性能是最好的,因为它是一次io,一次解析执行,由于此时占位符个数应该是不定的,不建议使用服务端预编译机制,更不建议客户端缓存,需要注意一次批量的包大小。
  • max_allowed_packet: 需要确定服务端该配置的大小,单个包超过该值会抛异常
  • autoGenerateTestcaseScript=true&traceProtocol=true: 可以在jdbc driver端看到与服务端的交互日志
  • show variables like '%log%';set global general_log=on;show variables like 'general_log_file' 可以查看服务端sql日志

Mysql PS 执行详细参考

Oracle待续

image.png
  • oracle jdbc driver未开源,其原理资料并不多,其默认就支持预编译,详细交互不是很清楚
  • oracle服务端的预编译应该全局性的,而不是单个连接范围内的
  • 客户端机制应该没太多特殊性,同mysql类似
    Oracle JDBC Developer's Guide
    引用参考https://blog.csdn.net/theorytree/article/details/7331096
    oracle执行sql过程
    oracle sql执行顺序

oracle里面除了查询结果集缓存外,还有SQL缓存,缓存在SGA共享区域,可以使用软解析,而跳过更解析。

语句缓存的好处
• ORACLE执行SQL语句时,先将SQL语句的字串通过一个哈希算法得出一个哈希值,然后检查共享池中是否已存在这个哈希值,若有就用已缓存的执行计划来执行这个语句(CACHE HIT 缓存命中),若没有(CACHE MISS 缓存缺失)则需进行解析,解析需要完成下面的工作:

Ø 语法检查;
Ø 语义检查,看参考对象是否存在,类型是否正确;
Ø (如果是CBO优化模式)收集参考对象的统计;
Ø 检查用户的权限是否足够;
Ø 从许多可能的执行路径中选择一条作为执行计划;
Ø 生成语句的编译版本(P-CODE)。

• 解析是一个昂贵的操作,因为过程中需要消耗许多资源;
• 最大化CACHE HIT是调整共享池的目标

DBMS.png

你可能感兴趣的:(PreparedStatement&Batch)