关于java:如何利用日志链路追踪程序执行的慢-SQL

31次阅读

共计 1569 个字符,预计需要花费 4 分钟才能阅读完成。

导读:查看 SQL 的执行效率,不难想到应用 explain 剖析慢查问,然而前提是你须要十分理解业务背景。否则很难精准定位到。

零碎都是逐步演进的,一个零碎在运行中必须是依据场景逐步地进步优化性能。高并发就是对资源的节约的考验,这种考验除了更换优良和先进的技术,优化架构,还在于从小处登程,对尽可能节约的资源进行节约。

而在一个零碎的数据拜访中,零碎的瓶颈往往是来自于数据库,因而咱们要尽可能减少对数据库的拜访!

一、背景

有没有遇到这种状况,领导忽然安顿一件事件:这几个接口压测指标太低须要针对性优化一下。

当然现实的状况下你对业务场景十分相熟,能够大略定位问题来剖析业务精准评估哪些 SQL 会有性能瓶颈。

而后开始百度:如何进步 SQL 执行效率?

通过 explain、show profile 和 trace 等诊断工具来剖析慢查问。

然而大多数状况下业务线过长,不可能一个人实现。波及到各种策略模式、监听动作。想间接定位到点还是须要输入申请发动后所触发的执行的 SQL 以及执行效率。这里效率单单指代 SQL 执行的工夫。

指标明确后开始整活吧。

二、增加 JDBC 追踪

持续前一篇文章的话题:如何利用好日志链路追踪做性能剖析?

▐ SQL 执行工夫公式

要想解决此类问题首先的剖析,SQL 执行工夫计算如何来划分?SQL 的语句执行过程大抵如下图所示。

如果想统计 SQL 执行工夫。所以对于程序而言能够失去粗略公式

SQL 执行工夫 = 提取数据之后工夫 - 语法解析开始工夫

▐ 增加减少 JDBC 追踪

浏览过 Hibernate 或者 MyBatis 等长久化框架的应该比拟理解 Statement 位于 java.sql 根底包下

Statement 提供了用于执行动态 SQL 语句并返回它产生的后果的对象。默认状况下,每个 Statement 对象只能同时关上一个 ResultSet 对象。

因而,如果一个 ResultSet 对象的读取与另一个的读取交织,则每个对象都必须由不同的 Statement 对象生成。如果存在关上的对象,则 Statement 接口中的所有执行办法都会隐式敞开该 Statement 的以后 ResultSet 对象。

持续查看源码能够发现在 Statement 提供了用于执行办法后,PreparedStatement 预编译 SQL 语句的对象。SQL 语句被预编译并存储在 PreparedStatement 对象中。而后能够应用此对象屡次无效地执行此语句。

为了验证这个思路,能够借鉴其余定制化数据库驱动。


定义 StatementWraper 实现 Statement 提供了用于执行动态 SQL 语句并返回它产生的后果的对象。

记录日志详情

public class PreparedStatementWraper extends StatementWraper
  implements PreparedStatement {
 private PreparedStatement raw;

 private String sql;

 public PreparedStatementWraper(PreparedStatement raw, String sql) {super(raw);
  this.raw = raw;
  this.sql = sql;
 }

 // ========== 记录日志 ==========
 @Override
 public ResultSet executeQuery() throws SQLException {long startTime = System.currentTimeMillis();
  try {return raw.executeQuery();
  } finally {doLog("executeQuery", sql, startTime);
  }
 }
....
j

最初日志输入应用 logback 组件进行日志采集

对这类问题先前有做介绍

  • 微服务分布式架构中,如何实现日志链路跟踪?
  • 如何利用好日志链路追踪做性能剖析?

正文完
 0