设为首页 加入收藏

TOP

Oracle不使用索引的几种情况列举(五)
2017-01-24 08:15:17 】 浏览:610
Tags:Oracle 使用 索引 情况 列举
------
?
Predicate Information (identified by operation id):
---------------------------------------------------
?
? 2 - access(MOD("X",999)=1)


情况4:
考虑以下情况,已经对一个字符钱建立了索引。这个列只包含数据数据。如果使用以下语法来查询:
select * from t where indexed_colum=5;
注意查询中的数字5是常数5(而不是一个字符串),此时就没有使用INDEXED_COLUMN上的索引。这是因为,前面的查询等价于以下查询:
select * from t where to_number(indexed_column)=5;
我们对这个列隐式地应用了一个函数,如情况3所述,这就会禁止使用这个索引。
zx@ORCL>create table t2 (x char(1) constraint t2_pk primary key ,y date);
?
Table created.
?
zx@ORCL>insert into t2 values('5',sysdate);
?
1 row created.
?
zx@ORCL>commit;
?
Commit complete.
?
zx@ORCL>exec dbms_stats.gather_table_stats(USER,'T2',cascade=>true);
?
PL/SQL procedure successfully completed.
?
zx@ORCL>explain plan for select * from t2 where x=5;
?
Explained.
?
zx@ORCL>select * from table(dbms_xplan.display);
?
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 1513984157
?
--------------------------------------------------------------------------
| Id? | Operation? ? ? ? | Name | Rows? | Bytes | Cost (%CPU)| Time? ? |
--------------------------------------------------------------------------
|? 0 | SELECT STATEMENT? |? ? ? |? ? 1 |? ? 12 |? ? 3? (0)| 00:00:01 |
|*? 1 |? TABLE ACCESS FULL| T2? |? ? 1 |? ? 12 |? ? 3? (0)| 00:00:01 |
--------------------------------------------------------------------------
?
Predicate Information (identified by operation id):
---------------------------------------------------
?
? 1 - filter(TO_NUMBER("X")=5)
?
Note
-----
? - dynamic sampling used for this statement (level=2)


可以看到,它会全面扫描表;另外即使我们对查询给出了以下提示:
zx@ORCL>explain plan for select /*+ index(t2 t2_pk) */ * from t2 where x=5;
?
Explained.
?
zx@ORCL>select * from table(dbms_xplan.display);
?
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 3365102699
?
-------------------------------------------------------------------------------------
| Id? | Operation? ? ? ? ? ? ? ? ? | Name? | Rows? | Bytes | Cost (%CPU)| Time? ? |
-------------------------------------------------------------------------------------
|? 0 | SELECT STATEMENT? ? ? ? ? ? |? ? ? |? ? 1 |? ? 10 |? ? 2? (0)| 00:00:01 |
|? 1 |? TABLE ACCESS BY INDEX ROWID| T2? ? |? ? 1 |? ? 10 |? ? 2? (0)| 00:00:01 |
|*? 2 |? INDEX FULL SCAN? ? ? ? ? | T2_PK |? ? 1 |? ? ? |? ? 1? (0)| 00:00:01 |
-------------------------------------------------------------------------------------
?
Predicate Information (identified by operation id):
---------------------------------------------------
?
? 2 - filter(TO_NUMBER("X")=5)


在此使用了索引,但是并不像我们想像中那样对索引完成唯一扫描(UNIQUE SCAN),而是完成了全面扫描(FULL SCAN)。原因从最后一行输出可以看出:filter(TO_NUMBER("X")=5)。这里对这个数据库列应用了一个隐式函数。X中存储的字符串必须转换为一个数字,之后才能与值5进行比较。在此无法把5转换为一个串,因为我们的NLS(国家语言支持)设置会控制5转换成串时的具体形式(而这是不确定的,不同的NLS设置会有不同的控制),所以应当把串转为数据。而这样一样(由于应用也函数),就无法使用索引来快速地查找这一行了。如果只是执行串与串的比较:
zx@ORCL>explain plan for select * from t2 where x='5';
?
Explained.
?
zx@ORCL>select * from table(dbms_xplan.display);
?
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------

首页 上一页 2 3 4 5 6 下一页 尾页 5/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇RMAN无法删除归档日志 下一篇Oracle order by子句对NULL的排序

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目