一、慢查询到底是什么鬼?

大家应该都有过这样的体验:早上打开系统一看,某个报表页面加载了10秒还没出来,或者后台任务跑了一晚上还没完成。这时候DBA就会跳出来说:"这是慢查询搞的鬼!"

所谓慢查询,简单来说就是执行时间超过预期阈值的SQL语句。就像你去银行办业务,正常取号排队10分钟能搞定,结果有个窗口的业务员处理一笔转账花了2小时,后面排队的人全都炸锅了。

在OceanBase中,默认情况下执行时间超过1秒的查询就会被标记为慢查询。这个阈值可以通过参数调整,但1秒是个比较合理的起点。

二、OceanBase自带的慢查询分析利器

2.1 系统视图:v$sql_audit

OceanBase自带了一个超级实用的系统视图v$sql_audit,它就像是个全天候的SQL监控摄像头,记录了所有执行过的SQL语句及其执行详情。

-- 查询最近1小时内的慢查询
SELECT /*+ READ_CONSISTENCY(WEAK) */ 
    sql_id,
    user_name,
    db_name,
    elapsed_time/1000 as elapsed_sec,
    execute_time/1000 as execute_sec,
    queue_time/1000 as queue_sec,
    get_scheduler_time/1000 as scheduler_sec,
    sql_text
FROM v$sql_audit
WHERE tenant_id = 'your_tenant'
  AND elapsed_time > 1000000  -- 超过1秒
  AND request_time > SYSDATE - INTERVAL '1' HOUR
ORDER BY elapsed_time DESC
LIMIT 100;

注释说明:

  • elapsed_time:总耗时(微秒)
  • execute_time:实际执行时间
  • queue_time:排队等待时间
  • get_scheduler_time:获取调度器时间
  • sql_id:SQL的唯一标识符,可用于后续跟踪

2.2 日志分析工具:ob_admin

除了系统视图,OceanBase还提供了ob_admin这个命令行工具,可以直接分析observer的日志文件,提取慢查询信息。

# 分析最近24小时的慢查询日志
ob_admin slog_tool -f observer.log -q -t 1000000 -d 24h

# 输出示例:
# [2023-07-15 14:23:45.123] [user1@tenant1] [3.456s] SELECT * FROM large_table WHERE ...
# [2023-07-15 15:12:33.456] [user2@tenant1] [2.789s] UPDATE orders SET status='paid' WHERE ...

参数说明:

  • -f:指定日志文件路径
  • -q:只查询慢查询日志
  • -t:时间阈值(微秒),这里是1秒
  • -d:时间范围,24小时

三、实战案例分析

3.1 案例一:缺少索引导致的慢查询

我们来看一个真实案例。某电商平台发现"订单查询"接口在促销期间响应很慢,通过v$sql_audit找到了问题SQL:

SELECT o.order_id, o.create_time, u.user_name, p.product_name
FROM orders o
JOIN users u ON o.user_id = u.user_id
JOIN products p ON o.product_id = p.product_id
WHERE o.create_time > '2023-07-01'
  AND o.status = 'pending'
ORDER BY o.create_time DESC;

分析发现:

  1. orders表有上亿条数据
  2. create_time和status字段没有联合索引
  3. 每次查询都全表扫描

解决方案是添加适当的索引:

CREATE INDEX idx_orders_status_time ON orders(status, create_time);

3.2 案例二:事务持有锁时间过长

另一个常见问题是事务持有锁时间过长,导致其他查询被阻塞。通过以下查询可以找出锁等待情况:

SELECT /*+ READ_CONSISTENCY(WEAK) */
    l.lock_mode,
    l.lock_obj_type,
    l.lock_obj_id,
    s.sql_text,
    s.elapsed_time/1000 as elapsed_sec,
    s.user_name,
    s.db_name
FROM v$lock_wait l
JOIN v$sql_audit s ON l.session_id = s.session_id
WHERE l.tenant_id = 'your_tenant'
ORDER BY s.elapsed_time DESC;

四、高级分析技巧

4.1 使用SQL Plan分析执行计划

找到慢查询后,下一步是分析它的执行计划。OceanBase提供了EXPLAIN命令:

EXPLAIN EXTENDED
SELECT /*+ READ_CONSISTENCY(WEAK) */ 
    COUNT(*) 
FROM orders 
WHERE create_time > '2023-07-01'
  AND status = 'pending';

关键要看:

  • 是否走了正确的索引
  • 是否有全表扫描
  • 是否有不必要的排序操作
  • 预估行数和实际行数是否匹配

4.2 定期收集慢查询统计

建议定期收集慢查询统计信息,建立基线以便对比:

-- 创建慢查询统计表
CREATE TABLE slow_query_stats (
    collect_time TIMESTAMP,
    sql_id VARCHAR(256),
    sql_text CLOB,
    avg_elapsed_sec NUMBER,
    max_elapsed_sec NUMBER,
    call_count NUMBER,
    PRIMARY KEY (collect_time, sql_id)
);

-- 每小时收集一次统计
INSERT INTO slow_query_stats
SELECT 
    SYSDATE,
    sql_id,
    MAX(sql_text),
    AVG(elapsed_time)/1000000,
    MAX(elapsed_time)/1000000,
    COUNT(*)
FROM v$sql_audit
WHERE tenant_id = 'your_tenant'
  AND elapsed_time > 1000000
  AND request_time > SYSDATE - INTERVAL '1' HOUR
GROUP BY sql_id;

五、应用场景与最佳实践

5.1 典型应用场景

  1. 生产环境性能监控:实时监控慢查询,及时发现性能问题
  2. 版本发布验证:新版本上线后检查是否有SQL性能回退
  3. 容量规划:通过慢查询趋势预测未来资源需求
  4. SQL审核:识别需要优化的SQL语句

5.2 技术优缺点

优点:

  • 内置功能,无需额外部署
  • 实时性强,可以立即发现问题
  • 信息全面,包含执行计划、等待事件等

缺点:

  • 系统视图数据是内存中的,重启后会丢失
  • 大量记录会影响性能,需要合理配置采样率
  • 需要一定的OceanBase知识才能正确解读数据

5.3 注意事项

  1. 在生产环境查询v$sql_audit时,建议加上READ_CONSISTENCY(WEAK)提示,避免影响业务
  2. 长时间运行的聚合查询可能消耗大量内存,记得加LIMIT
  3. 日志分析工具ob_admin需要在服务器本地执行,注意权限控制
  4. 定期归档历史慢查询数据,避免主表过大

六、总结

OceanBase提供的慢查询分析工具非常强大,从实时监控的系统视图到离线的日志分析工具,覆盖了各种场景的需求。通过本文介绍的方法,你可以:

  1. 快速定位系统中的性能瓶颈
  2. 分析SQL执行计划的优劣
  3. 识别锁等待等并发问题
  4. 建立长期的性能监控机制

记住,慢查询优化是个持续的过程,需要定期检查和分析。希望这篇文章能帮助你更好地使用OceanBase的这些工具,让你的数据库跑得更快更稳!