SQL索引字段使用函数操作导致不走索引

今天在做SQL Tuning的时候遇到一个典型的example,立个Flag,梳理知识点,在这里也做个分享,就是我们在写SQL的时候如果对索引字段使用函数炒作,则导致该SQL不走索引扫描查询,导致SQL性能下降。

SQL如下:

SELECT NVL(A.USER_NAME_C, NVL(A.USER_NAME_E, A.USER_CODE)) USER_NAME, 
 A.TEL_NO, 
 A.FAX_NATION_CODE || A.FAX_AREA_CODE || A.FAX_LOCAL_NO FAX_NO 
 FROM AAA3010 A, AAA3009 B 
 WHERE A.CUST_SEQ_NO = B.CUST_SEQ_NO AND CUST_TYPE = 1 
 AND DECODE(A.USER_CODE,  'CN19000125', 1, 'WHL', 1, 2) = 1; 

该SQL对A.USER_CODE字段使用DECODE函数,所以导致没有走Index扫描查询,如下该SQL的执行计划:

Execution Plan
----------------------------------------------------------
Plan hash value: 2797870618

-------------------------------------------------------------------------------------------
| Id  | Operation                    | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |            |    20 |   920 |    56   (2)| 00:00:01 |
|   1 |  NESTED LOOPS                |            |    20 |   920 |    56   (2)| 00:00:01 |
|   2 |   NESTED LOOPS               |            |    62 |   920 |    56   (2)| 00:00:01 |
|*  3 |    TABLE ACCESS FULL         | AAA3010    |    62 |  2356 |    43   (0)| 00:00:01 |
|*  4 |    INDEX UNIQUE SCAN         | AAA3009_PK |     1 |       |     1   (0)| 00:00:01 |
|*  5 |   TABLE ACCESS BY INDEX ROWID| AAA3009    |     1 |     8 |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------

看该Table结构,发现该Table的组合Index字段是(USER_CODE, CUST_SEQ_NO),如下图:
在这里插入图片描述

但是SQL对Index栏位调用Decode函数导致查询无法走索引扫描,通常如果有可替代方案则最好是不要对Index栏位使用函数,这里我们可以对该SQL拿掉Decode函数,改用In的方式查询,则查询时走索引扫描,提高SQL性能。

即修改成如下:

DECODE(A.USER_CODE,  'CN19000125', 1, 'WHL', 1, 2) = 1;  AND A.USER_CODE in('CN19000125','WHL');

则走Index扫描查询,如下该SQL的执行计划:

Execution Plan
----------------------------------------------------------
Plan hash value: 3932238443

---------------------------------------------------------------------------------------------
| Id  | Operation                      | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |            |     2 |    92 |     2   (0)| 00:00:01 |
|   1 |  NESTED LOOPS                  |            |     2 |    92 |     2   (0)| 00:00:01 |
|   2 |   NESTED LOOPS                 |            |     2 |    92 |     2   (0)| 00:00:01 |
|   3 |    INLIST ITERATOR             |            |       |       |            |          |
|   4 |     TABLE ACCESS BY INDEX ROWID| AAA3010    |     2 |    76 |     1   (0)| 00:00:01 |
|*  5 |      INDEX RANGE SCAN          | AAA3010_PK |     2 |       |     1   (0)| 00:00:01 |
|*  6 |    INDEX UNIQUE SCAN           | AAA3009_PK |     1 |       |     1   (0)| 00:00:01 |
|*  7 |   TABLE ACCESS BY INDEX ROWID  | AAA3009    |     1 |     8 |     1   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------

你可能感兴趣的:(SQL,Tuning)