查看: 2933|回复: 5

[原创] 基于COST优化,oracle什么情况不走索引

[复制链接]
认证徽章
论坛徽章:
2
2011新春纪念徽章
日期:2011-02-18 11:43:352012新春纪念徽章
日期:2012-01-04 11:54:26
发表于 2010-11-29 15:50 | 显示全部楼层 |阅读模式
今天具体开发的同事提出这样一个问题
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 有时会更快,尤其是当查询的数据量占整个表的比重较大时。
匿名  发表于 2010-11-30 20:22
顶!

使用道具

回复
论坛徽章:
86
2015中国数据库技术大会纪念徽章
日期:2015-04-24 16:04:24马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11优秀写手
日期:2013-12-18 09:29:11日产
日期:2013-10-17 08:44:39马自达
日期:2013-08-26 16:28:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-23 16:55:51马上有房
日期:2014-02-19 11:55:14
发表于 2010-12-30 13:24 | 显示全部楼层
选择度问题

使用道具 举报

回复
论坛徽章:
86
2015中国数据库技术大会纪念徽章
日期:2015-04-24 16:04:24马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11优秀写手
日期:2013-12-18 09:29:11日产
日期:2013-10-17 08:44:39马自达
日期:2013-08-26 16:28:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-23 16:55:51马上有房
日期:2014-02-19 11:55:14
发表于 2010-12-30 13:24 | 显示全部楼层
2楼是个什么情况?

使用道具 举报

回复
论坛徽章:
11
2010新春纪念徽章
日期:2010-03-01 11:08:27SQL大赛参与纪念
日期:2011-04-13 12:08:172010广州亚运会纪念徽章:空手道
日期:2011-03-08 15:29:592011新春纪念徽章
日期:2011-02-18 11:43:362010广州亚运会纪念徽章:台球
日期:2011-01-26 10:41:28数据库板块每日发贴之星
日期:2010-12-10 01:01:022010广州亚运会纪念徽章:网球
日期:2010-12-09 13:11:342010广州亚运会纪念徽章:篮球
日期:2010-12-06 14:28:04辩论纪念章
日期:2010-11-15 10:46:13ITPUB9周年纪念徽章
日期:2010-10-08 09:28:52
发表于 2010-12-30 13:35 | 显示全部楼层
pub貌似出问题了,时间乱七八糟的

使用道具 举报

回复
论坛徽章:
14
ITPUB9周年纪念徽章
日期:2010-10-08 09:28:52沸羊羊
日期:2015-03-04 14:43:43马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11福特
日期:2013-10-14 21:18:25凯迪拉克
日期:2013-09-23 23:01:572013年新春福章
日期:2013-02-25 14:51:242012新春纪念徽章
日期:2012-01-04 11:49:54ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412011新春纪念徽章
日期:2011-02-18 11:43:33
发表于 2010-12-30 13:39 | 显示全部楼层
1 、不要用analyze
2、返回的cardinality都不同,一個55,另一個是1
3、樓主看一下SQL 的dynamic sampling

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 
京ICP备09055130号-4  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表