高效的SQL(隐式转换导致不走索引)

高效的SQL(隐式转换导致不走索引)

 

1、创建实验表doudou,索引创建在varchar2类型的id列上,索引名DOUDOU_INDEX

doudou@TEST> select count(*) from doudou;

 

  COUNT(*)

----------

      1000

doudou@TEST> select index_name,table_owner,table_name,TABLE_TYPE, PCT_FREE,BUFFER_POOL,TEMPORARY from user_indexes where table_name='DOUDOU';

INDEX_NAME          TABLE_OWNE TABLE_NAME TABLE_TYPE               PCT_FREE BUFFER_POOL    TE

-------------------- ---------- ---------- ---------------------- ---------- -------------- --

DOUDOU_INDEX       DOUDOU     DOUDOU     TABLE                          10 DEFAULT        N

 

2、开启执行计划,并执行不同的2条SQL,并观察执行计划

doudou@TEST> set timing on

doudou@TEST> set autot on

doudou@TEST> select id from doudou where id=3;

 

ID

----------------------------------------

3

 

Elapsed: 00:00:00.01

 

Execution Plan

----------------------------------------------------------

Plan hash value: 845489848

 

----------------------------------------------------------------------------

| Id  | Operation         | Name   | Rows  | Bytes | Cost (%CPU)| Time     |

----------------------------------------------------------------------------

|   0 | SELECT STATEMENT  |        |     1 |    12 |     3   (0)| 00:00:01 |

|*  1 |  TABLE ACCESS FULL| DOUDOU |     1 |    12 |     3   (0)| 00:00:01 |

----------------------------------------------------------------------------

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   1 - filter(TO_NUMBER("ID")=3)

【这里有to_number的转换,导致没有走索引,所以,编写高效的SQL也要注意索引列的类型,不要让数据库帮你隐式转换。隐式转换之后不走索引。】

Note

-----

   - dynamic sampling used for this statement

 

 

Statistics

----------------------------------------------------------

        314  recursive calls

          0  db block gets

         58  consistent gets

          0  physical reads

          0  redo size

        404  bytes sent via SQL*Net to client

        400  bytes received via SQL*Net from client

          2  SQL*Net roundtrips to/from client

          6  sorts (memory)

          0  sorts (disk)

          1  rows processed

 

doudou@TEST> select id from doudou where id='3';

 

ID

----------------------------------------

3

 

Elapsed: 00:00:00.01

 

Execution Plan

----------------------------------------------------------

Plan hash value: 3961861220

 

---------------------------------------------------------------------------------

| Id  | Operation        | Name         | Rows  | Bytes | Cost (%CPU)| Time     |

---------------------------------------------------------------------------------

|   0 | SELECT STATEMENT |              |     1 |    12 |     1   (0)| 00:00:01 |

|*  1 |  INDEX RANGE SCAN| DOUDOU_INDEX |     1 |    12 |     1   (0)| 00:00:01 |

---------------------------------------------------------------------------------

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   1 - access("ID"='3')

 

Note

-----

   - dynamic sampling used for this statement

 

 

Statistics

----------------------------------------------------------

          9  recursive calls

          0  db block gets

         14  consistent gets

          0  physical reads

          0  redo size

        404  bytes sent via SQL*Net to client

        400  bytes received via SQL*Net from client

          2  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

          1  rows processed

 

总结:

编写SQL的时,where语句过滤条件中请注意索引列的类型,不要让oracle做隐式转换,因为隐式转换是不走索引的。

 

附表:

实验环境

sys@TEST>  select * from v$version;

BANNER

--------------------------------------------------------------------------------

Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Prod

PL/SQL Release 10.2.0.4.0 - Production

CORE    10.2.0.4.0      Production

TNS for Linux: Version 10.2.0.4.0 - Production

NLSRTL Version 10.2.0.4.0 – Production

sys@TEST> show parameter optimizer_mode

NAME                                 TYPE                   VALUE

------------------------------------ ---------------------- --------------------------

optimizer_mode                       string                 ALL_ROWS

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值