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

旅游网站开发的流程网站推广途径及要点

旅游网站开发的流程,网站推广途径及要点,网站制作 牛商网 岳阳 公司,什么网站可以兼职做效果图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.hkea.cn/news/14277442/

相关文章:

  • 织梦网站上传数据库微信 wordpress搜索
  • 自己做下载类网站免费申请商家收款码
  • 行业网站盈利模式国外网站建设的发展
  • 网站建设与管理 pdfwordpress 需要ftp
  • 电商首页模板网站阿凡达网站建设网
  • 建站网站知乎服装图案素材网站
  • php网站的数据库在哪网站建设实训意义
  • 网站建站和项目部署一样吗做公司网站要那些资料
  • 西安演出公司网站建设集团网站 wordpress
  • 网站改版方案ppt订阅号可以做微网站
  • 广西建设协会网站黑龙江建设网站
  • 格力电器的网站建设评价wordpress按最后评论排序
  • 网站建设推广视频深圳做网站可用乐云seo十年
  • 漳州最具口碑的网站建设wordpress wpenqueuescript
  • 深圳网站建设 易通鼎网站建设与网页设计开题报告
  • 网页 网站网站开发可以用哪些语言
  • 什么网站做电脑系统好校园兼职网站建设
  • 基础网站建设素材国内开源建站cms
  • 徐州住房与城乡建设部网站青岛谁优化网站做的好处
  • 各类东莞微信网站建设推广网站如何做
  • 中英文网站建设需要懂英语吗网页qq登陆保护怎么关
  • 网站推广的英文content有口碑的合肥网站建设
  • 梅州网站建设wordpress搬家后空白
  • 雄安网站建设优化公司wordpress访问权限
  • 找人做网站注意哪些网站链接失效怎么做
  • 做淘宝主要看哪些网站cuteftp可以上传网站吗
  • 网站开发用什么代码vi企业形象设计公司
  • 济南网站建设成之运维开网店被运营公司骗了怎么办
  • 做游戏网站需要哪些许可句容建设网站
  • 网站改备案吗flash网站教程