基于COST优化,oracle什么情况不走索引

今天具体开发的同事提出这样一个问题

SQL> set autotrace traceonly explain
SQL> select * from xxx  where aac001 = '111';

Execution Plan
----------------------------------------------------------

---------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)|
---------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |    55 | 22275 |     3   (0)|
|   1 |  TABLE ACCESS FULL| xxx |    55 | 22275 |     3   (0)|
---------------------------------------------------------------

Note
-----

在xxx.aac001上是存在索引的,但为什么不走索引呢?

接到这个问题,首先排除该索引是否失效了

SQL> select index_name,status from user_indexes where index_name = 'IDX_XXX_AAC
001';

INDEX_NAME                     STATUS
------------------------------ --------
IDX_XXX_AAC001                VALID

答案是否定的。接着对表和索引进行了分析

analyze index idx_xxx_aac001 validate structure;

analyze table xxx  delete  statistics;

analyze table xxx compute  statistics;

仍然是全表扫描,奇怪了,隐式转换不可能,开发人员还不至于犯如此错误

因为是开发库,数量变化可能没有规律,所以重新rebuild一下索引吧

SQL> set autotrace traceonly explain
SQL> select * from xxx where aac001 = '111';

Execution Plan
----------------------------------------------------------

---------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)|
---------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |    65 | 26260 |     3   (0)|
|   1 |  TABLE ACCESS FULL| xxx |    65 | 26260 |     3   (0)|
---------------------------------------------------------------

Note
-----
   - 'PLAN_TABLE' is old version

SQL>

没有起作用

不是组合索引,该列也不可能为空,那是什么原因呢

SQL> select count(*) from xxx;

  COUNT(*)
----------
        68

 

SQL> select count(*) from xxx where aac001 = '111';

  COUNT(*)
----------
        65

 

换个人试一下

SQL> explain plan for select * from xxx  where aac001 = '123';

Explained.

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------


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

----

| Id  | Operation                   | Name            | Rows  | Bytes | Cost (%C

PU)|

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

----

|   0 | SELECT STATEMENT            |                 |     1 |   404 |     2

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------

(0)|

|   1 |  TABLE ACCESS BY INDEX ROWID| xxx           |     1 |   404 |     2
(0)|

|   2 |   INDEX RANGE SCAN          | IDX_xxx_AAC001 |     1 |       |     1
(0)|

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

----


PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------


Note
-----
   - 'PLAN_TABLE' is old version

12 rows selected.

答案出来了,就是这个问题,由于是开发库,没有真实的数据,所有数据均为开发人员手动造的,辛苦了

以前总是在说,基于COST优化:表数据量小,全表扫描比走索引效率高
很简单,你的表数据可能占用一个块,索引也是占用一个块,
如果全表扫描,只需读一个块,而使用索引则要读两个块,
显然使用索引成本更高,因此oracle决定使用全表扫描。

但真的碰到了,还是很难想到。通过这次,oracle优化器的智慧让我折服了,对其印象更加深刻了,并不是所有情况使用索引都会加快查询速度,full scan table 有时会更快,尤其是当查询的数据量占整个表的比重较大时。

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/13726712/viewspace-680555/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/13726712/viewspace-680555/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值