通过


性能记录器和回调

下载 JDBC 驱动程序

从版本 13.4 开始,Microsoft JDBC Driver for SQL Server 提供了用于跟踪关键驱动程序操作计时的性能指标框架。 可以使用此框架观察和分析连接和语句执行行为,帮助识别应用程序与 SQL Server 交互时的延迟瓶颈。

指标可通过两种机制提供,这些机制可以独立使用或一起使用:

  • 编程回调 - 注册PerformanceLogCallback以便在应用程序代码中接收指标。
  • Java 日志记录 - 订阅专用 java.util.logging 记录器以捕获日志输出中的指标。

被跟踪的活动

驱动程序跟踪两个级别的活动:连接和语句。

连接级别活动

活动 说明
CONNECTION 建立连接的总时间,包括所有子活动。
PRELOGIN TDS 登录前与服务器协商所需的时间。
LOGIN TDS 登录和身份验证握手过程的时间。
TOKEN_ACQUISITION 使用 Microsoft Entra 身份验证时获取联合身份验证令牌的时间。

语句级活动

活动 说明
STATEMENT_REQUEST_BUILD 生成 TDS 请求的客户端时间(参数绑定、SQL 处理、数据包构造)。 仅限于计时,不会跟踪异常。
STATEMENT_FIRST_SERVER_RESPONSE 从发送请求到接收第一个服务器响应的时间。 仅用于计时;不跟踪异常。
STATEMENT_PREPARE 时间。sp_prepareprepareMethod=prepare
STATEMENT_PREPEXEC 通过sp_prepexec的合并准备和执行时间。
STATEMENT_EXECUTE 语句执行时间(sp_executesqlsp_execute,直接 SQL 或批处理)。

启用性能指标

第一个选项:注册一个回调函数

注册一个 PerformanceLogCallback 以编程方式接收性能数据:

SQLServerDriver.registerPerformanceLogCallback(new PerformanceLogCallback() {
    @Override
    public void publish(PerformanceActivity activity, int connectionId,
            long durationMs, Exception exception) {
        // Connection-level metrics
        System.out.printf("Activity: %s, Connection: %d, Duration: %d ms%n",
                activity, connectionId, durationMs);
    }

    @Override
    public void publish(PerformanceActivity activity, int connectionId,
            int statementId, long durationMs, Exception exception) {
        // Statement-level metrics
        System.out.printf("Activity: %s, Connection: %d, Statement: %d, Duration: %d ms%n",
                activity, connectionId, statementId, durationMs);
    }
});

选项 2:配置 Java 日志记录

为性能指标记录器在FINE级别配置java.util.logging

logging.properties文件中:

com.microsoft.sqlserver.jdbc.PerformanceMetrics.Connection.level = FINE
com.microsoft.sqlserver.jdbc.PerformanceMetrics.Statement.level = FINE
handlers = java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level = FINE

或者以编程方式:

Logger.getLogger("com.microsoft.sqlserver.jdbc.PerformanceMetrics.Connection")
      .setLevel(Level.FINE);
Logger.getLogger("com.microsoft.sqlserver.jdbc.PerformanceMetrics.Statement")
      .setLevel(Level.FINE);

准备方法对语句操作的影响

跟踪 PreparedStatement 的活动取决于 prepareMethod 连接属性。 有关详细信息 prepareMethod,请参阅 “设置连接属性”。

prepareMethod 设置 首次执行 第二次执行 第三次加上执行
prepexec(默认值) STATEMENT_EXECUTEsp_executesql STATEMENT_PREPEXECsp_prepexec STATEMENT_EXECUTEsp_execute
prepare STATEMENT_PREPARE + STATEMENT_EXECUTE STATEMENT_EXECUTE STATEMENT_EXECUTE
none STATEMENT_EXECUTE (直接 SQL) STATEMENT_EXECUTE (直接 SQL) STATEMENT_EXECUTE (直接 SQL)

注释

使用默认设置 prepexec 时,驱动程序会延迟准备(假设使用一次)。 第二次执行使用 sp_prepexec (结合准备和执行)。 从第三次执行开始,缓存的句柄将通过 sp_execute 重复使用。 若要强制 sp_prepexec 进行第一次调用,请将连接属性 enablePrepareOnFirstPreparedStatementCall 设置为 true

示例日志输出

以下输出显示了使用默认prepexec设置的PreparedStatement在三次连续执行中跟踪的活动:

ConnectionID:1, StatementID:1 Request build time, duration: 8ms
ConnectionID:1, StatementID:1 First server response, duration: 17ms
ConnectionID:1, StatementID:1 Statement execute, duration: 75ms        ← 1st call: sp_executesql
ConnectionID:1, StatementID:1 Request build time, duration: 9ms
ConnectionID:1, StatementID:1 First server response, duration: 0ms
ConnectionID:1, StatementID:1 Statement prepexec, duration: 0ms        ← 2nd call: sp_prepexec
ConnectionID:1, StatementID:1 Request build time, duration: 0ms
ConnectionID:1, StatementID:1 First server response, duration: 0ms
ConnectionID:1, StatementID:1 Statement execute, duration: 0ms         ← 3rd call: sp_execute

另请参阅

使用 JDBC 驱动程序设置连接属性来提高性能和可靠性