查看: 5173|回复: 14

谁能解释一下create index i on t(c desc)的用途

[复制链接]
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
跳转到指定楼层
1#
发表于 2009-11-13 10:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_5010.htm
看了官方文档,只看懂就是desc当作函数索引,其他没看出来
论坛徽章:
1088
金色在线徽章
日期:2007-04-25 04:02:08金色在线徽章
日期:2007-06-29 04:02:43金色在线徽章
日期:2007-03-11 04:02:02在线时间
日期:2007-04-11 04:01:02在线时间
日期:2007-04-12 04:01:02在线时间
日期:2007-03-07 04:01:022008版在线时间
日期:2010-05-01 00:01:152008版在线时间
日期:2011-05-01 00:01:342008版在线时间
日期:2008-06-03 11:59:43ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30
2#
发表于 2009-11-13 12:08 | 只看该作者
默认是asc升序索引,desc就是降序索引
降序索引好像只能在CBO情况下使用,如果按索引键降序排序,能快速排序,如果按索引键升序排序,那么可能走 DESCENDING

create table test as select * from dba_users;

create index idx_username_desc on test(username desc);

  begin
   dbms_stats.gather_table_stats('DINGJUN123','TEST');
end;

explain plan for select * from test where username>'SYS' order by username;
select * from table(dbms_xplan.display);

Plan hash value: 3259162827

--------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                   |     5 |   495 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID | TEST              |     5 |   495 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN DESCENDING| IDX_USERNAME_DESC |     1 |       |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access(SYS_OP_DESCEND("USERNAME")<HEXTORAW('ACA6ACFF') )
       filter(SYS_OP_UNDESCEND(SYS_OP_DESCEND("USERNAME"))>'SYS' AND
              SYS_OP_DESCEND("USERNAME")<HEXTORAW('ACA6ACFF') )
              
              
explain plan for select * from test where username>'SYS' order by username desc;
select * from table(dbms_xplan.display);

1        Plan hash value: 921883186
2         
3        -------------------------------------------------------------------------------------------------
4        | Id  | Operation                   | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
5        -------------------------------------------------------------------------------------------------
6        |   0 | SELECT STATEMENT            |                   |     5 |   495 |     2   (0)| 00:00:01 |
7        |   1 |  TABLE ACCESS BY INDEX ROWID| TEST              |     5 |   495 |     2   (0)| 00:00:01 |
8        |*  2 |   INDEX RANGE SCAN          | IDX_USERNAME_DESC |     1 |       |     1   (0)| 00:00:01 |
9        -------------------------------------------------------------------------------------------------
10         
11        Predicate Information (identified by operation id):
12        ---------------------------------------------------
13         
14           2 - access(SYS_OP_DESCEND("USERNAME")<HEXTORAW('ACA6ACFF') )
15               filter(SYS_OP_UNDESCEND(SYS_OP_DESCEND("USERNAME"))>'SYS' AND
16                      SYS_OP_DESCEND("USERNAME")<HEXTORAW('ACA6ACFF') )

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
3#
 楼主| 发表于 2009-11-13 12:28 | 只看该作者
看不出2执行计划的差别

使用道具 举报

回复
论坛徽章:
1088
金色在线徽章
日期:2007-04-25 04:02:08金色在线徽章
日期:2007-06-29 04:02:43金色在线徽章
日期:2007-03-11 04:02:02在线时间
日期:2007-04-11 04:01:02在线时间
日期:2007-04-12 04:01:02在线时间
日期:2007-03-07 04:01:022008版在线时间
日期:2010-05-01 00:01:152008版在线时间
日期:2011-05-01 00:01:342008版在线时间
日期:2008-06-03 11:59:43ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30
4#
发表于 2009-11-13 12:46 | 只看该作者
原帖由 〇〇 于 2009-11-13 12:28 发表
看不出2执行计划的差别

INDEX RANGE SCAN DESCENDING
INDEX RANGE SCAN
难道不差别吗?我这里数据量小,其他的应该没有什么差别,如果数据量大,cost,cpu之类的有可能有差别,没有测试

使用道具 举报

回复
论坛徽章:
6
奥运会纪念徽章:射箭
日期:2008-07-01 22:14:12ITPUB8周年纪念徽章
日期:2009-09-27 10:21:212010年世界杯参赛球队:斯洛文尼亚
日期:2009-12-29 09:03:172010世博会纪念徽章
日期:2010-08-27 18:42:29紫蛋头
日期:2011-06-27 09:30:09复活蛋
日期:2011-07-01 17:42:09
5#
发表于 2009-11-13 12:49 | 只看该作者
单独列索引用DESC感觉没有什么特殊的用途,
但联合索引使用了DESC在topN 查询中会起很大的作用
例如 create index i on t(b,c desc,d)

使用道具 举报

回复
论坛徽章:
1
生肖徽章2007版:狗
日期:2009-10-08 19:42:37
6#
发表于 2009-11-13 13:09 | 只看该作者
2 |   INDEX RANGE SCAN DESCENDING| IDX_USERNAME_DESC
2 |   INDEX RANGE SCAN          | IDX_USERNAME_DESC
这两个地方的区别

使用道具 举报

回复
论坛徽章:
1
生肖徽章2007版:狗
日期:2009-10-08 19:42:37
7#
发表于 2009-11-13 13:17 | 只看该作者

回复 #4 dingjun123 的帖子

我测试了1百万数据的表 两个没有什么区别

使用道具 举报

回复
论坛徽章:
1088
金色在线徽章
日期:2007-04-25 04:02:08金色在线徽章
日期:2007-06-29 04:02:43金色在线徽章
日期:2007-03-11 04:02:02在线时间
日期:2007-04-11 04:01:02在线时间
日期:2007-04-12 04:01:02在线时间
日期:2007-03-07 04:01:022008版在线时间
日期:2010-05-01 00:01:152008版在线时间
日期:2011-05-01 00:01:342008版在线时间
日期:2008-06-03 11:59:43ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30
8#
发表于 2009-11-13 13:50 | 只看该作者
原帖由 chengboxian 于 2009-11-13 12:49 发表
单独列索引用DESC感觉没有什么特殊的用途,
但联合索引使用了DESC在topN 查询中会起很大的作用
例如 create index i on t(b,c desc,d)

回去查查资料学习下

使用道具 举报

回复
论坛徽章:
821
授权会员
日期:2007-08-10 01:06:30山治
日期:2019-11-15 22:34:592015年新春福章
日期:2015-03-06 11:57:31暖羊羊
日期:2015-03-04 14:50:37马上有钱
日期:2014-12-21 16:14:33马上加薪
日期:2014-11-23 19:24:42 2014年世界杯参赛球队: 德国
日期:2014-07-09 15:28:06ITPUB元老
日期:2008-08-24 00:06:57会员2007贡献徽章
日期:2007-09-26 18:42:10托尼托尼·乔巴
日期:2020-03-23 10:49:16
9#
发表于 2009-11-13 17:05 | 只看该作者
降序索引,大数据量排序时有用

使用道具 举报

回复
论坛徽章:
519
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
10#
发表于 2009-11-13 22:49 | 只看该作者
Oracle 9i10g编程艺术 BY THOMAS KYTE
11.2.3 降序索引
降序索引(descending index)是Oracle8i 开始引入的,用以扩展B*树索引的功能。它允许在索引
中以降序(从大到小的顺序)存储一列,而不是升序(从小到大)存储。在之前的Oracle 版本(即Oracle8i
以前的版本)中,尽管语法上也支持DESC(降序)关键字,但是一般都会将其忽略,这个关键字对于索引
中数据如何存储或使用没有任何影响。不过,在Oracle8i 及以上版本中,DESC 关键字确实会改变创建和
使用索引的方式。
Oracle 能往前读索引,这种能力已不算新,所以你可能会奇怪我们为什么会兴师动众地说这个特性
很重要。例如,如果使用先前的表T,并如下查询这个表:
Oracle 会往前读索引。这个计划最后没有排序步骤:数据已经是有序的。不过,如果你有一组列,
其中一些列按升序排序(ASC),另外一些列按降序排序(DESC),此时这种降序索引就能派上用场了,例如:
ops$tkyte@ORA10G> set autotrace traceonly explain
ops$tkyte@ORA10G> select owner, object_type
2 from t
3 where owner between 'T' and 'Z'
4 and object_type is not null
5 order by owner DESC, object_type DESC;
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=82 Card=11395 Bytes=170925)

Oracle 会往前读索引。这个计划最后没有排序步骤:数据已经是有序的。不过,如果你有一组列,
其中一些列按升序排序(ASC),另外一些列按降序排序(DESC),此时这种降序索引就能派上用场了,例如:
ops$tkyte@ORA10G> select owner, object_type
2 from t
3 where owner between 'T' and 'Z'
4 and object_type is not null
5 order by owner DESC, object_type ASC;
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=85 Card=11395 Bytes=170925)
11.0 SORT (ORDER BY) (Cost=85 Card=11395 Bytes=170925)
2 1 INDEX (RANGE SCAN) OF 'T_IDX' (INDEX) (Cost=82 Card=11395 ...
Oracle 不能再使用(OWNER, OBJECT_TYPE, OBJECT_NAME)上的索引对数据排序。它可以往前读得到
按OWNER DESC 排序的数据,但是现在还需要“向后读“来得到按OBJET_TYPE 顺序排序(ASC)数据。此时
Oracle 的实际做法是,它会把所有行收集起来,然后排序。但是如果使用DESC 索引,则有:

ops$tkyte@ORA10G> create index desc_t_idx on t(owner desc,object_type asc);
Index created.
ops$tkyte@ORA10G> exec dbms_stats.gather_index_stats( user, 'DESC_T_IDX' );
PL/SQL procedure successfully completed.
ops$tkyte@ORA10G> select owner, object_type
2 from t
3 where owner between 'T' and 'Z'
4 and object_type is not null
5 order by owner DESC, object_type ASC;
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=2 Card=11395 Bytes=170925)
11.0 INDEX (RANGE SCAN) OF 'DESC_T_IDX' (INDEX) (Cost=2 Card=11395 ...
现在,我们又可以读取有序的数据了,在这个计划的最后并没有额外的排序步骤。应当注意,除非
init.ora 中的compatible 参数设置为8.11.0 或更高,否则CREATE INDEX 上的DESC 选项会被悄悄地忽略,
没有警告,也不会产生错误,因为这是先前版本的默认行为。
注意查询中最好别少了ORDER BY。即使你的查询计划中包含一个索引,但这并不表示数据会以“某
种顺序“返回。要想从数据库以某种有序的顺序获取数据,惟一的办法就是在查询中包括一个ORDER
BY 子句。ORDER BY 是无可替代的。

使用道具 举报

回复

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

本版积分规则 发表回复

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