1. 介绍
事情是这样的,UAT 环境的测试小伙伴向我扔来一个小 bug,说是一个放大镜的查询很慢,转几分钟才出数据,我立马上开发环境试了一下,很快啊我说😏,放大镜的数据立马就出来了,然后我登录 UAT 环境一看,诶是有些慢😕 ,于是开始了我的排查之旅...
2. 过程
首先我立马拿到了执行的 SQL 在开发环境的数据库执行了下,很快,都在 1s 左右,感觉没啥问题啊,然后我就在页面上点点点,发现好像上面有一个相关联的下拉框,如果选中的有数据,再点击这个放大镜就会慢一点,然后我登录 UAT 环境一试,哦不是这个问题,于是只能开始排查 SQL 了。
百度了一圈 Oracle 性能调优,大多很空泛,没有一个通用的、具体的、可执行的步骤。但是找到了排查前必备的查看执行计划explain plan。
以下是正儿八经的优化过程👇:
2.1 查看该条 SQL 的执行计划
2.1.1 生成执行计划
在要排查的SQL前面加上explain plan for,例如以下的例子:
explain plan for SELECT * FROM SOURCE_LISTEX_202101 WHERE pass_id = '012101200123001025061320201201002852';
2.1.2 查看执行计划
推荐使用该 SQL 去查询执行计划👍 (为什么?因为简短好记😂)
select * from table(dbms_xplan.display)
或者
SELECT plan_table_output FROM TABLE(DBMS_XPLAN.DISPLAY('PLAN_TABLE'));
查出来的应该是这个样子:
Plan hash value: 1335523602 ----------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ----------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 44479 | 38M| 17411 (1)| 00:03:29 | | 1 | TABLE ACCESS BY INDEX ROWID | SOURCE_LISTEX_202101 | 44479 | 38M| 17411 (1)| 00:03:29 | |* 2 | INDEX RANGE SCAN | LISTEX_202101_PASS_ID | 17792 | | 3 (0)| 00:00:01 | ----------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("PASS_ID"='012101200123001025061320201201002852')
而且如果你的 SQL 长了之后会发现,Operation 列是会有缩进的,缩进代表层级关系,就很乱😥,这里我推荐 Datagrip👍的右键可视化Explain plan。
使用方法为:选中SQL,右键Explain Plan,就可以查看啦,大概长这个样子: