已索引

2025.05.20 19:50 分, DBA 接到应用人员电话,说是变更后应用日志报 broken pipe 错误。
变更内容为:将历史表 H 修改为 H.OLD 后,重新创建了一个 H 表,然后将最近一个月的数据从 H.OLD 表导入 H 表。

DBA 登录系统后,查询当前没锁等待现象,但有两个会话在 H 表上持有锁。
根据会话信息找到当前会话正在执行的 SQL 语句为 UPDATE H .... WHERE ID = .. 语句。
这个 UPDATE 语句一直在 v$session 中,表明该语句一直在执行。

查询该语句的执行计划:

alter session set nls_date_format='yyyy-mm-dd hh24:mi;ss';
set lines 200;
set pages 800;
col operation for a18;
select INST_ID,PLAN_HASH_VALUE,ID,PARENT_ID,OPERATION,OPTIONS,OBJECT_NAME,OBJECT_TYPE,TIMESTAMP 
from GV$SQL_PLAN
where SQL_ID='b8drmbgrxt51y' 
order by TIMESTAMP,ID;

PLAN_HASH_VALUE         ID  PARENT_ID OPERATION                      OPTIONS      OBJECT_NAME                     OBJECT_TYPE          TIMESTAMP
--------------- ---------- ---------- ------------------------------ ------------ ------------------------------- -------------------- -------------------
     2794891096          0            UPDATE STATEMENT                                                                                 2022-08-03 00:20;01
     2794891096          1          0 UPDATE                                      XX_YQ_BUSIXXXX_GATEWAY                               2022-08-03 00:20;01
     2794891096          2          1 INDEX                          UNIQUE SCAN  SYS_C0054478                    INDEX (UNIQUE)       2022-08-03 00:20;01
     2670273405          0            UPDATE STATEMENT                                                                                 2025-05-20 18:25;06
     2670273405          1          0 UPDATE                                      XX_YQ_BUSIXXXX_GATEWAY                               2025-05-20 18:25;06
     2670273405          2          1 TABLE ACCESS                   FULL         XX_YQ_BUSIXXXX_GATEWAY          TABLE                2025-05-20 18:25;06

发现该语句执行计划发生了变化,之前走的索引,现在走的全表扫描。查看具体的执行计划:

SQL> select PLAN_TABLE_OUTPUT from table(dbms_xplan.display_cursor('b8drmbgrxt51y',null,'allstats last')); 
Plan hash value: 2670273405

---------------------------------------------------------------------------------------------
| Id  | Operation          | Name                   | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | UPDATE STATEMENT   |                        |       |       |     5 (100)|          |
|   1 |  UPDATE            | XX_YQ_BUSIXXXX_GATEWAY |       |       |            |          |
|   2 |   TABLE ACCESS FULL| XX_YQ_BUSIXXXX_GATEWAY |     1 |  2946 |     5   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------

统计 SQL 语句的执行时间,发现该表在 18:30 左右刚刚建立好的时候,语句执行很快,都在 1s 内。
后面时间慢慢增长,18:40左右增长到 30s左右,19:10后开始超过 120s(业务超时时间)。

很明显,随着数据的增长(将最近一个月的数据从 H.OLD 表导入 H 表),全表扫描的性能急剧下降,问题出现在没有走索引而走的全表扫描上。
进一步分析, H.OLD 表有且只有一个缺省索引,在 ID 列上,H 表没有任何索引。

在 H 表的 ID 列上创建索引后,问题解决。

PLAN_HASH_VALUE         ID  PARENT_ID OPERATION                      OPTIONS      OBJECT_NAME                     OBJECT_TYPE          TIMESTAMP
--------------- ---------- ---------- ------------------------------ ------------ ------------------------------- -------------------- -------------------
     2794891096          0            UPDATE STATEMENT                                                                                 2022-08-03 00:20;01
     2794891096          1          0 UPDATE                                      XX_YQ_BUSIXXXX_GATEWAY                               2022-08-03 00:20;01
     2794891096          2          1 INDEX                          UNIQUE SCAN  SYS_C0054478                    INDEX (UNIQUE)       2022-08-03 00:20;01
     2670273405          0            UPDATE STATEMENT                                                                                 2025-05-20 18:25;06
     2670273405          1          0 UPDATE                                      XX_YQ_BUSIXXXX_GATEWAY                               2025-05-20 18:25;06
     2670273405          2          1 TABLE ACCESS                   FULL         XX_YQ_BUSIXXXX_GATEWAY          TABLE                2025-05-20 18:25;06
     3887297726          0            UPDATE STATEMENT                                                                                 2025-05-20 20:41;32
     3887297726          1          0 UPDATE                                      XX_YQ_BUSIXXXX_GATEWAY                               2025-05-20 20:41;32
     3887297726          2          1 INDEX                          UNIQUE SCAN  SYS_C0084606                    INDEX (UNIQUE)       2025-05-20 20:41;32


Plan hash value: 3887297726

---------------------------------------------------------------------------------------------
| Id  | Operation          | Name                   | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | UPDATE STATEMENT   |                        |       |       |     3 (100)|          |
|   1 |  UPDATE            | XX_YQ_BUSIXXXX_GATEWAY |       |       |            |          |
|   2 |   INDEX UNIQUE SCAN| SYS_C0084606           |     1 |  2946 |     2   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------

再次查询 SQL 语句的执行时间,都在 1s 内完成。

-- By 许望(RHCA、OCM、VCP)
最后修改:2025 年 05 月 21 日 05 : 41 PM
如果觉得我的文章对你有用,请随意赞赏