查询无法用到函数索引

[复制链接]
查看11 | 回复9 | 2006-5-6 22:39:09 | 显示全部楼层 |阅读模式
本帖最后由 aiirii 于 2013-8-8 17:24 编辑
测试步骤如下:
create table test1.test2 as select * from dba_objects;
create index test1.idx_test2_2 on test1.test2(case temporary when 'Y' then 'Y' end);
exec dbms_stats.gather_table_stats(OWNNAME => 'TEST1', tabname => 'TEST2', CASCADE => TRUE);

SQL> set autot traceonly
SQL>
SQL>
SQL> select * from test2 where temporary = 'Y';
77 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 300966803
---------------------------------------------------------------------------
| Id| Operation | Name| Rows| Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT| |77 |7777 |86 (2)| 00:00:01 |
|*1 |TABLE ACCESS FULL| TEST2 |77 |7777 |86 (2)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("TEMPORARY"='Y')
请教问题出在那? 如何利用上这索引?
请参考这哥们的 blog: http://luw.itpub.net/post/43737/531102#comments 是否我理解错了?

回复

使用道具 举报

千问 | 2006-5-6 22:39:09 | 显示全部楼层
你的谓词有函数么?
select * from test2 where case temporary when 'Y' then 'Y' end='Y';
回复

使用道具 举报

千问 | 2006-5-6 22:39:09 | 显示全部楼层
2楼说的对。
试试select * from test2 where (case temporary when 'Y' then 'Y' end)='Y';
另外你的Y值占比多少?oracle最终看cost,如果比例很小可以使用虚拟列,虚拟列上加索引。否则还不如全表扫描。
回复

使用道具 举报

千问 | 2006-5-6 22:39:09 | 显示全部楼层
good.


回复

使用道具 举报

千问 | 2006-5-6 22:39:09 | 显示全部楼层
请参考这个链接 http://luw.itpub.net/post/43737/531102
第四点里面的例子
回复

使用道具 举报

千问 | 2006-5-6 22:39:09 | 显示全部楼层
case temporary when 'Y' then 'Y' 函数索引的用法是你的谓词就是这个函数
回复

使用道具 举报

千问 | 2006-5-6 22:39:09 | 显示全部楼层
函数索引,在查询中要使用对应函数,另外就看cost 消耗 了。
回复

使用道具 举报

千问 | 2006-5-6 22:39:09 | 显示全部楼层
请参考这个链接 http://luw.itpub.net/post/43737/531102, 我还无法正确理解;
4. 能在某些行上面建索引而忽略其他行,以节省空间。某些情景下可代替位图索引,比位图索引有更好的并发行,而且空间也小(二) 应用例子
1. 函数索引仅在某些行上建索引的例子。
场景:假设1个表的字段process_flag只有两个值,N表示新记录未处理,处理后变为Y。大多数记录为Y。主要操作是查询process_flag='N'的记录进行处理,然后将process_flag值改为'Y'
如果使用B*tree索引,索引空间大,BLEVEL高。如果使用位图索引,并发修改性能又差。这时可使用函数索引(只在值为N的记录上):
create index processed_flag_idx
on big_table( case temporary when 'N' then 'N' end );
回复

使用道具 举报

千问 | 2006-5-6 22:39:09 | 显示全部楼层
看 oracle database 9i/10g/11g 编程艺术吧原文有的
回复

使用道具 举报

千问 | 2006-5-6 22:39:09 | 显示全部楼层
hurong09 发表于 2013-8-12 17:34
看 oracle database 9i/10g/11g 编程艺术吧原文有的

原文也只是举了个用法,但没有使用的例子;
实际上,我们查询用的是 where temporaty = 'Y'这个条件,怎么利用上索引?
回复

使用道具 举报

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

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行