从版本 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_executesql、sp_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_EXECUTE(sp_executesql) |
STATEMENT_PREPEXEC(sp_prepexec) |
STATEMENT_EXECUTE(sp_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 驱动程序设置连接属性来提高性能和可靠性