一、慢查询到底是什么鬼?
大家应该都有过这样的体验:早上打开系统一看,某个报表页面加载了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;
分析发现:
- orders表有上亿条数据
- create_time和status字段没有联合索引
- 每次查询都全表扫描
解决方案是添加适当的索引:
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 典型应用场景
- 生产环境性能监控:实时监控慢查询,及时发现性能问题
- 版本发布验证:新版本上线后检查是否有SQL性能回退
- 容量规划:通过慢查询趋势预测未来资源需求
- SQL审核:识别需要优化的SQL语句
5.2 技术优缺点
优点:
- 内置功能,无需额外部署
- 实时性强,可以立即发现问题
- 信息全面,包含执行计划、等待事件等
缺点:
- 系统视图数据是内存中的,重启后会丢失
- 大量记录会影响性能,需要合理配置采样率
- 需要一定的OceanBase知识才能正确解读数据
5.3 注意事项
- 在生产环境查询v$sql_audit时,建议加上READ_CONSISTENCY(WEAK)提示,避免影响业务
- 长时间运行的聚合查询可能消耗大量内存,记得加LIMIT
- 日志分析工具ob_admin需要在服务器本地执行,注意权限控制
- 定期归档历史慢查询数据,避免主表过大
六、总结
OceanBase提供的慢查询分析工具非常强大,从实时监控的系统视图到离线的日志分析工具,覆盖了各种场景的需求。通过本文介绍的方法,你可以:
- 快速定位系统中的性能瓶颈
- 分析SQL执行计划的优劣
- 识别锁等待等并发问题
- 建立长期的性能监控机制
记住,慢查询优化是个持续的过程,需要定期检查和分析。希望这篇文章能帮助你更好地使用OceanBase的这些工具,让你的数据库跑得更快更稳!
评论