11.2SQL查询追踪

分类: 数据库监控和追踪

SQL 查询追踪

欢迎回到第 11 章的学习。在上一节,我们学习了数据库监控概述。现在我们要学习 SQL 查询追踪,这是数据库性能监控的核心。

本节将学习:Spring Data JPA 自动追踪、查询参数追踪、慢查询识别、以及查询优化建议。

Spring Data JPA 自动追踪

Spring Data JPA 自动追踪的作用是什么? 自动追踪 Spring Data JPA 执行的 SQL 查询,无需手动添加代码。

如何启用自动追踪? OpenTelemetry 的 Spring Boot 集成会自动追踪 JPA 查询,无需额外配置。

追踪的信息包括哪些呢?

第一个:SQL 语句。 执行的 SQL 查询语句。

第二个:查询参数。 SQL 查询的参数值。

第三个:执行时间。 查询的执行时间。

第四个:结果集大小。 查询返回的结果数量。

第五个:数据库连接信息。 使用的数据库连接信息。

自动追踪示例:

@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {
    List<Order> findByUserId(String userId);
    List<Order> findByStatus(String status);
}

// OpenTelemetry These queries will be tracked automatically
@Service
public class OrderService {
    @Autowired
    private OrderRepository orderRepository;
    
    public List<Order> getOrdersByUser(String userId) {
        // Auto tracking:SELECT * FROM orders WHERE user_id = ?
        return orderRepository.findByUserId(userId);
    }
}

追踪的 Span 属性:

  • db.system
    : 数据库类型(如 "mysql")
  • db.name
    : 数据库名称
  • db.operation
    : 操作类型(如 "SELECT")
  • db.statement
    : SQL 查询语句
  • db.sql.table
    : 表名
  • db.connect_string
    : 连接字符串

查询参数追踪

查询参数追踪的作用是什么? 记录 SQL 查询的参数值,帮助理解查询上下文,方便问题排查。

如何追踪查询参数? OpenTelemetry 会自动在 Span 属性中记录查询参数,包括参数名称和值。

查询参数包括哪些呢?

第一个:位置参数。 使用

?
占位符的参数。

第二个:命名参数。 使用

:name
占位符的参数。

第三个:参数值。 参数的实际值(注意隐私保护)。

查询参数追踪配置:

# application.properties
# Enable query parameter tracking
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.format_sql=true

# OpenTelemetry provisioning
otel.instrumentation.jdbc.query-parameters.enabled=true

慢查询识别

慢查询识别的作用是什么? 识别执行时间过长的查询,优化查询性能,提升应用响应速度。

如何识别慢查询? 设置慢查询阈值(如 100 毫秒),超过阈值的查询被标记为慢查询。

慢查询识别策略:

第一种:固定阈值。 设置固定的时间阈值,如 100 毫秒。

第二种:动态阈值。 根据查询类型设置不同的阈值。

第三种:统计分析。 使用统计方法识别异常慢的查询。

慢查询识别配置:

# application.properties
# Set the slow query threshold (ms))
otel.instrumentation.jdbc.slow-query-threshold=100

慢查询分析:

// in Grafana Medium Queries Slow Queries
// TraceQL: {db.operation="SELECT"} && {duration > 100ms}

// or record slow queries in the log
@Aspect
@Component
public class SlowQueryAspect {
    @Around("@annotation(org.springframework.data.jpa.repository.Query)")
    public Object logSlowQuery(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object result = joinPoint.proceed();
        long duration = System.currentTimeMillis() - start;
        
        if (duration > 100) {
            log.warn("Slow query detected: {}ms, method: {}", 
                duration, joinPoint.getSignature().getName());
        }
        
        return result;
    }
}

查询优化建议

查询优化建议的作用是什么? 基于追踪数据,提供查询优化建议,提升查询性能。

优化建议包括哪些呢?

第一个:索引优化。 建议添加或优化索引。

第二个:查询重写。 建议重写查询语句,优化查询逻辑。

第三个:分页优化。 建议使用分页查询,减少数据传输量。

第四个:缓存策略。 建议使用缓存,减少数据库查询。

查询优化示例:

// Before optimization: full table scan
@Query("SELECT o FROM Order o WHERE o.userId = :userId")
List<Order> findByUserId(@Param("userId") String userId);

// After optimization: Adding an index
// ALTER TABLE orders ADD INDEX idx_user_id (user_id);

// Before optimization: no pagination
List<Order> findAll();

// After optimization: Use pagination
Page<Order> findAll(Pageable pageable);

// Before optimization:N+1 Inquire questions
@OneToMany
List<OrderItem> items;

// After optimization: use JOIN FETCH
@Query("SELECT o FROM Order o JOIN FETCH o.items WHERE o.id = :id")
Order findByIdWithItems(@Param("id") Long id);

本节小结

在本节中,我们学习了 SQL 查询追踪:

第一个是 Spring Data JPA 自动追踪。 自动追踪 SQL 查询,无需手动添加代码,记录 SQL 语句、参数、执行时间等信息。

第二个是查询参数追踪。 记录 SQL 查询的参数值,帮助理解查询上下文,方便问题排查。

第三个是慢查询识别。 识别执行时间过长的查询,设置阈值,优化查询性能。

第四个是查询优化建议。 基于追踪数据,提供索引优化、查询重写、分页优化、缓存策略等建议。

SQL 查询追踪流程: 自动追踪 SQL 查询 → 记录查询参数 → 识别慢查询 → 提供优化建议 → 优化查询性能。

这就是 SQL 查询追踪。通过 SQL 查询追踪,我们可以全面了解数据库查询的性能和优化机会。

在下一节,我们将学习数据库连接池监控。学习如何监控连接池使用情况。