oracle联合索引匹配

背景: 根据awr检测发现某业务查询耗时较长,1.25s per

oracle联合索引匹配

报告显示全表查询

oracle联合索引匹配

sql较简单:

select commonstru0_.PMR_COMMON_STRUCT_ID as PMR_COMMON_STRUCT_1_7_,
       commonstru0_.COMPOUND_ID          as COMPOUND_ID2_7_,
       commonstru0_.CONTROL_CLASS        as CONTROL_CLASS3_7_,
       ...
  from pmr.PMR_COMMON commonstru0_
 where commonstru0_.HOSPITAL_ID = :1
   and commonstru0_.COMPOUND_ID = :2
   and commonstru0_.PATIENT_SN = :3
   and commonstru0_.ELEMENT_CODE = :4

现要对全表扫描sql进行索引优化,进行如下实验:

1. 无索引,filter全表扫描,cost较高

----------------------------------------------------------------------------------------
| Id  | Operation          | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                   |     1 |   273 |  2515   (1)| 00:00:01 |
|   1 |  SORT ORDER BY     |                   |     1 |   273 |  2515   (1)| 00:00:01 |
|*  2 |   TABLE ACCESS FULL| PMR_COMMON_STRUCT |     1 |   273 |  2514   (1)| 00:00:01 |
----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - filter("COMMONSTRU0_"."HOSPITAL_ID"='12211422' AND 
              "COMMONSTRU0_"."PATIENT_SN"='300144202008261' AND 
              "COMMONSTRU0_"."COMPOUND_ID"='4652008544' AND 
              "COMMONSTRU0_"."ELEMENT_CODE"='ZDYJ')

2.  全量联合索引,所有子句均添加索引

oracle联合索引匹配

----------------------------------------------------------------------------------------------------------------
| Id  | Operation                            | Name                    | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                     |                         |     1 |   273 |     3  (34)| 00:00:01 |
|   1 |  SORT ORDER BY                       |                         |     1 |   273 |     3  (34)| 00:00:01 |
|   2 |   TABLE ACCESS BY INDEX ROWID BATCHED| PMR_COMMON_STRUCT       |     1 |   273 |     2   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN                  | IDX_PMR_COMMON_STRUCT_1 |     1 |       |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   3 - access("COMMONSTRU0_"."HOSPITAL_ID"='12211422' AND "COMMONSTRU0_"."PATIENT_SN"='300144202008261' 
              AND "COMMONSTRU0_"."COMPOUND_ID"='4652008544' AND "COMMONSTRU0_"."ELEMENT_CODE"='ZDYJ')

      结论:索引范围查找,但索引占用空间较大

3.  联合索引排除差异较小的字段(hospital_Id),降低索引所占用空间(采用)

oracle联合索引匹配

----------------------------------------------------------------------------------------------------------------
| Id  | Operation                            | Name                    | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                     |                         |     1 |   273 |     3  (34)| 00:00:01 |
|   1 |  SORT ORDER BY                       |                         |     1 |   273 |     3  (34)| 00:00:01 |
|*  2 |   TABLE ACCESS BY INDEX ROWID BATCHED| PMR_COMMON_STRUCT       |     1 |   273 |     2   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN                  | IDX_PMR_COMMON_STRUCT_1 |     1 |       |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - filter("COMMONSTRU0_"."HOSPITAL_ID"='12211422')
   3 - access("COMMONSTRU0_"."PATIENT_SN"='300144202008261' AND 
              "COMMONSTRU0_"."COMPOUND_ID"='4652008544' AND "COMMONSTRU0_"."ELEMENT_CODE"='ZDYJ')

  结论:hospital_id 使用filter, 其他字段仍然可以命中索引

4. 调整where子句顺序,查看对命中联合索引的影响

oracle联合索引匹配

Plan hash value: 1093457038
 
----------------------------------------------------------------------------------------------------------------
| Id  | Operation                            | Name                    | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                     |                         |     1 |   273 |     3  (34)| 00:00:01 |
|   1 |  SORT ORDER BY                       |                         |     1 |   273 |     3  (34)| 00:00:01 |
|*  2 |   TABLE ACCESS BY INDEX ROWID BATCHED| PMR_COMMON_STRUCT       |     1 |   273 |     2   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN                  | IDX_PMR_COMMON_STRUCT_1 |     1 |       |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------------------

 结论:调整顺序前后的执行计划相同(Plan hash value: 1093457038 ),说明无需关注where子句的顺序,对命中索引没有影响,优化器自动处理了

上一篇:Maven 建立父子项目和跨项目调用内容的步骤


下一篇:1002-leetcode算法实现之查找共用字符-find-common-characters-python&golang实现