当前位置: 首页 > news >正文

旅游网站开发的流程手机app软件

旅游网站开发的流程,手机app软件,制作网页的要素,深圳有做网站的公司660元MySQL 驱动 Add Batch 优化实现 MySQL 驱动会在 JDBC URL 添加 rewriteBatchedStatements 参数时#xff0c;对 batch 操作进行优化。本文测试各种参数组合的行为#xff0c;并结合驱动代码简单分析。 batch参数组合行为 useServerPrepStmts 参数 PreparedStatement psmt…MySQL 驱动 Add Batch 优化实现 MySQL 驱动会在 JDBC URL 添加 rewriteBatchedStatements 参数时对 batch 操作进行优化。本文测试各种参数组合的行为并结合驱动代码简单分析。 batch参数组合行为 useServerPrepStmts 参数 PreparedStatement psmt connection.prepareStatement(DELETE FROM t_order WHERE order_id ?); psmt.setObject(1, 1); psmt.execute();开启: 使用服务端预编译先发送 prepared 语句再发送 excute 语句 不开启: mysql 驱动会将占位符填充后明文下发sql. 比如 DELETE FROM t_order WHERE order_id ?; 语句 MySQL 驱动会下发 DELETE FROM t_order WHERE order_id 1; allowMultiQueries 参数 Statement statement connection.createStatement(); statement.execute(DELETE FROM t_order WHERE order_id 1;DELETE FROM t_order WHERE order_id 2;);不开启: 服务端不支持 DELETE FROM t_order WHERE order_id 1;DELETE FROM t_order WHERE order_id 2; 这样的批量delete语句 开启: 支持多语句比如 DELETE FROM t_order WHERE order_id 1;DELETE FROM t_order WHERE order_id 2; rewriteBatchedStatements 参数 PreparedStatement psmt connection.prepareStatement(DELETE FROM t_order WHERE order_id ?); for (int i 1; i 500; i) {psmt.setObject(1, i);psmt.addBatch(); } psmt.executeBatch();不开启: batch 操作在 addBatch 时一条条下发参数值。 开启: 在执行 executeBatch 时,将 batch 操作改写后批量下发改写后的 SQL 比如 DELETE FROM t_order WHERE order_id 1;DELETE FROM t_order WHERE order_id 2;…;DELETE FROM t_order WHERE order_id 500; useServerPrepStmtsallowMultiQueries 参数 PreparedStatement psmt connection.prepareStatement(DELETE FROM t_order WHERE order_id ?;DELETE FROM t_order WHERE order_id ?;); psmt.execute();虽然开启了服务端预编译参数 useServerPrepStmts但是 MySQL JDBC 驱动会判断预编译 SQL 不支持 allowMultiQueries会直接转换成客户端预编译也就时会将占位符赋值后下发到 mysql。 比如对于以下 SQL: DELETE FROM t_order WHERE order_id ?;DELETE FROM t_order WHERE order_id ?; 客户端会将占位符填充后发送: DELETE FROM t_order WHERE order_id 1;DELETE FROM t_order WHERE order_id 2; useServerPrepStmtsrewriteBatchedStatements 参数 PreparedStatement psmt connection.prepareStatement(DELETE FROM t_order WHERE order_id ?); for (int i 1; i 500; i) {psmt.setObject(1, i);psmt.addBatch(); } psmt.executeBatch();对于 DELETE FROM t_order WHERE order_id ? 的 batch 语句 会转换成 DELETE FROM t_order WHERE order_id ?;DELETE FROM t_order WHERE order_id ?;多语句下发但是服务端返回不支持。 然后客户端再使用客户端预编译尝试发送(会先发送 set multi option on 包,执行完再关闭该标识)然后下发多语句 DELETE FROM t_order WHERE order_id 1;DELETE FROM t_order WHERE order_id 2;…;DELETE FROM t_order WHERE order_id 500; useServerPrepStmtsallowMultiQueriesrewriteBatchedStatements 参数 PreparedStatement psmt connection.prepareStatement(DELETE FROM t_order WHERE order_id ?); for (int i 1; i 500; i) {psmt.setObject(1, i);psmt.addBatch(); } psmt.executeBatch();当执行 batch delete 语句时 虽然开启了 useServerPrepStmts 预编译参数但是 MySQL JDBC 驱动会判断预编译 SQL 不支持 allowMultiQueries会直接转换成客户端预编译也就将占位符赋值后下发到服务端。 也就是发送 DELETE FROM t_order WHERE order_id 1;DELETE FROM t_order WHERE order_id 2;…;DELETE FROM t_order WHERE order_id 500; MySQL 驱动代码分析 下面结合驱动代码简单分析两组参数的流程: 1.useServerPrepStmtsrewriteBatchedStatementsallowMultiQueries 参数 // 测试 demo // jdbc:mysql://localhost:3306/test?serverTimezoneUTCuseSSLfalseallowPublicKeyRetrievaltrueuseServerPrepStmtstruecachePrepStmtstrueprepStmtCacheSize512prepStmtCacheSqlLimit8000rewriteBatchedStatementstrueallowMultiQueriestrue PreparedStatement psmt connection.prepareStatement(DELETE FROM t_order WHERE order_id ?); for (int i 1; i 500; i) {psmt.setObject(1, i);psmt.addBatch(); } psmt.executeBatch();MySQL驱动处理逻辑 1.prepareStatement 当执行 prepareStatement() 时因为开启了 useServerPrepStmts 参数所以会下发预编译 sql 给 server 端。 PreparedStatement psmt connection.prepareStatement(sql);相关调用栈如下 com.mysql.cj.jdbc.ConnectionImpl#prepareStatementcom.mysql.cj.jdbc.ConnectionImpl#canHandleAsServerPreparedStatement1.判断当前sql是否支持服务端预编译com.mysql.cj.jdbc.ServerPreparedStatement#getInstancecom.mysql.cj.jdbc.ServerPreparedStatement#serverPrepare2.下发预编译sqlcom.mysql.cj.ServerPreparedQuery#serverPreparecom.mysql.cj.protocol.a.NativeMessageBuilder#buildComStmtPreparecom.mysql.cj.NativeSession#sendCommand发包com.mysql.cj.protocol.a.NativeProtocol#readcom.mysql.cj.protocol.a.ColumnDefinitionReader#unpackField1.开启 useServerPrepStmts 参数(emulateUnsupportedPstmts 参数默认就为true)会再根据 canHandleAsServerPreparedStatement() 判断当前 sql 是否支持服务端预编译。 2.canHandleAsServerPreparedStatement()方法会通过 StringUtils._canHandleAsServerPreparedStatementNoCache() 方法检测 sql 是否可以支持服务端预编译。 com.mysql.cj.jdbc.ServerPreparedStatement#getInstance 发送预编译 sql 2.addBatch 添加参数即可不和服务端交互。 3.executeBatch 调用栈: com.mysql.cj.jdbc.StatementImpl#executeBatchcom.mysql.cj.jdbc.ClientPreparedStatement#executeBatchInternalcom.mysql.cj.jdbc.StatementImpl#statementBeginscom.mysql.cj.ServerPreparedQuery#statementBeginscom.mysql.cj.AbstractQuery#statementBeginscom.mysql.cj.AbstractPreparedQuery#getParseInfocom.mysql.cj.ParseInfo#canRewriteAsMultiValueInsertAtSqlLevel 是否支持insert values改写优化com.mysql.cj.jdbc.ClientPreparedStatement#executePreparedBatchAsMultiStatement 多语句执行优化com.mysql.cj.AbstractQuery#getBatchedArgscom.mysql.cj.AbstractPreparedQuery#computeBatchSize 计算批次大小com.mysql.cj.ServerPreparedQuery#computeMaxParameterSetSizeAndBatchSizecom.mysql.cj.jdbc.ClientPreparedStatement#generateMultiStatementForBatchcom.mysql.cj.jdbc.ConnectionImpl#prepareStatementcom.mysql.cj.jdbc.ConnectionImpl#prepareStatementcom.mysql.cj.jdbc.ServerPreparedStatement#setOneBatchedParameterSetcom.mysql.cj.jdbc.ClientPreparedStatement#executecom.mysql.cj.jdbc.ClientPreparedStatement#checkReadOnlySafeStatementcom.mysql.cj.protocol.a.NativeMessageBuilder#buildComQuerycom.mysql.cj.NativeSession#sendCommand由于开启了 rewriteBatchedStatements 参数并且 delelte batch size 大于 3,会通过 executePreparedBatchAsMultiStatement 优化成 批量 delete. // 开启 rewriteBatchedStatements 参数 if (!this.batchHasPlainStatements this.rewriteBatchedStatements.getValue()) {// batch size 3,则将 sql 转成 multi deleteif (!this.batchHasPlainStatements this.query.getBatchedArgs() ! null this.query.getBatchedArgs().size() 3 /* cost of option setting rt-wise */) {return executePreparedBatchAsMultiStatement(batchTimeout);} }executePreparedBatchAsMultiStatement 方法 计算需要分几个批次下发。正常500条sql一个批次即可。 // 根据上面得到的batch sql的长度确定分几个批次下发 multi sql; /*** Computes the optimum number of batched parameter lists to send* without overflowing max_allowed_packet.* * param numBatchedArgs* original batch size* return computed batch size*/ public int computeBatchSize(int numBatchedArgs) {long[] combinedValues computeMaxParameterSetSizeAndBatchSize(numBatchedArgs);long maxSizeOfParameterSet combinedValues[0];long sizeOfEntireBatch combinedValues[1];// 整个 batch sql 的长度不能超长正常走到这个分支里if (sizeOfEntireBatch this.maxAllowedPacket.getValue() - this.originalSql.length()) {return numBatchedArgs;}return (int) Math.max(1, (this.maxAllowedPacket.getValue() - this.originalSql.length()) / maxSizeOfParameterSet); }计算方法如下 // 计算 maxSizeOfParameterSet: 每个参数中最大的长度 // sizeOfEntireBatch: batch所有参数长度相加 /*** Computes the maximum parameter set size and the size of the entire batch given* the number of arguments in the batch.*/ Override protected long[] computeMaxParameterSetSizeAndBatchSize(int numBatchedArgs) {long sizeOfEntireBatch 1 /* com_execute */4 /* stmt id */ 1 /* flags */ 4 /* batch count padding */;long maxSizeOfParameterSet 0;for (int i 0; i numBatchedArgs; i) {ServerPreparedQueryBindValue[] paramArg ((ServerPreparedQueryBindings) this.batchedArgs.get(i)).getBindValues();long sizeOfParameterSet (this.parameterCount 7) / 8; // for isNullsizeOfParameterSet this.parameterCount * 2; // have to send typesServerPreparedQueryBindValue[] parameterBindings this.queryBindings.getBindValues();for (int j 0; j parameterBindings.length; j) {if (!paramArg[j].isNull()) {long size paramArg[j].getBoundLength();if (paramArg[j].isStream()) {if (size ! -1) {sizeOfParameterSet size;}} else {sizeOfParameterSet size;}}}sizeOfEntireBatch sizeOfParameterSet;if (sizeOfParameterSet maxSizeOfParameterSet) {maxSizeOfParameterSet sizeOfParameterSet;}}return new long[] { maxSizeOfParameterSet, sizeOfEntireBatch }; }拼接预编译sql,此时还有?号占位符 ((Wrapper) locallyScopedConn.prepareStatement(generateMultiStatementForBatch(numValuesPerBatch))).unwrap(java.sql.PreparedStatement.class);得到sql如下 DELETE FROM t_order WHERE order_id ?;DELETE FROM t_order WHERE order_id ?;......执行 prepareStatement将上面的批量delete语句执行预编译。 这里逻辑和第一步里的 prepareStatement 类似也需要判断当前批量delete sql是否支持服务端预编译。 这里可以看到开启 allowMultiQueries 参数之后驱动会查找 sql 里是否包含 ; 号如果包含不支持服务端预编译。后面会走客户端预编译流程。 客户端预编译执行批量delete 设置参数 // 给?号占位符塞值 batchedParamIndex setOneBatchedParameterSet(batchedStatement, batchedParamIndex, this.query.getBatchedArgs().get(batchCounter));执行批量delete语句 2.useServerPrepStmtsrewriteBatchedStatements 参数 1.下发预编译sql 2.设置 multi statement on 3.多语句预编译sql,执行返回失败 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near DELETE FROM t_order WHERE order_id ?;DELETE FROM t_order WHERE order_id ’ at line 1 代码就是服务端prepared返回失败会再用 client Prepare statement 重试 4.client Prepare statement 重新批量delete 语句
http://www.dnsts.com.cn/news/135675.html

相关文章:

  • 网站 服务器 域名亚马逊雨林火灾
  • 专注合肥网站推广如皋网站建设公司
  • 贸易公司网站设计建设部网站下载
  • h5企业网站定制排名重庆品牌设计公司排行
  • 公司做宣传网站做网站用Linux还是win
  • 网站内容框架app模板图片
  • 互联网网站建设水平个人网页设计dw
  • 域名绑定网站需要多久上海专业网站建设渠道
  • 做古风人物小图的网站或软件上海缘魁网站建设
  • 网站建设小工具一级消防工程师考试大纲
  • 3 建设营销型网站流程我的世界自己做披风网站
  • 网站专题效果图怎么做昌吉网站建设公司
  • 永嘉县住房和城乡建设局网站深圳市房产交易中心官网
  • 织梦网站密码北京制作网站报价
  • 域名和网站名要一样吗母婴网站建设 社区
  • 上海网站推广价格原单手表网站
  • 怎样建网站平台网站设计师如何让客户信任你
  • 互联科技行业网站免费追剧永久免费app
  • 防水补漏东莞网站建设芜湖市公司网站建设哪家好
  • 怎样做天猫网站视频河南秋实网站建设
  • 深圳做网站google推广徐州数据网站建设介绍
  • 桐城市美丽乡村建设专题网站文案馆logo设计
  • 建设部特殊工种查询网站热门的网站模板下载
  • 建设网站的拓扑图上海市嘉定建设局网站
  • 导购网站需要备案吗芜湖做网站优化
  • 网站空间是怎么开通的seo站长工具下载
  • 怎样用dw做网站柚子皮wordpress
  • 做一个电商网站多少钱wordpress 7天热门
  • 很有设计感的企业网站建设局平台
  • 专业的做网站公司做穿越火线的网站资料