倒序索引提升order by DESC性能
为什么倒序索引会比较快,当数据插入进表时, Oracle已经为索引键值排好序了(前导列排序),从左往右是按小到大排序的。而一般扫描索引时也是从左往右扫描的,当需要将最大(晚)的时间数据在前面显示时几乎需要将整个索引全部扫描(有时会自动倒序扫描),效率很低。
创建一个倒序索引,如:
create index t_idx on table_name(time desc)索引最左边的值就是最大(晚)的时间插入的数据,好像数据就是往左增长一样,此时索引从左往右扫描的时候,第一个就是最大(晚)的时间了。
案例介绍
本案例通过Dynatrace(DT)查看执行情况,分析定位当前Oracle资源池CPU使用率居高不下的问题,通过优化分页查询SQL语句及索引,使Oracle资源池CPU使用率降至正常范围。
一、问题现象:
某系统Oracle cpu_count是8C,整机Oracle资源池是28C,因此数据库合理的CPU使用率不应超过28.57%。然而在Oracle资源池数据库CPU限制放开的情况下,进行测试,发现数据库CPU资源使用率超过80%。
1、 第一阶段:
通过DT监控的结果,抓取到cpu消耗高的SQL语句,并通过SqlDeveloper,分析SQL语句的cost。优化分页相关写法后,语句cost略有降低,但数据库CPU消耗率仍然很高。原因是压测中为了模拟极端情况,将分页条件设置为第2000页,导致查询数据量极高。
语句为:
select doctitle, crtime, docpuburl from( select A.*, rownum r from (select * from wcmdocument where docchannel =5436 and docstatus=10 order by crtime desc) A where rownum <=10*2000 ) B where r>=10*1999+1;2、 第二阶段:
为了进一步优化语句cost,逐步排查表上索引的效率。通过观察SqlDeveloper执行计划的结果,发现优化分页语句后的SQL仍会进行全表扫描。执行cost如下:

其中,该语句走到的WCM_TEST为普通索引, candidate在使用索引前后都是304448,没有任何减少。此时,整体cost为40805。

3、 第三阶段:
针对该功能业务SQL分析,其中order by crtime desc涉及到crtime字段的排序操作,而普通索引WCM_TEST中该字段采用默认升序方式建立。故引入倒序索引WCM_TEST2,该索引上crtime以倒序方式建立。具体如下:
通过hint方式,启用新索引后,该语句执行计划显示,candidate在使用索引后骤减至20000,整体cost也随之骤减至2701。若尝试将分页输入条件改为第1页,效果更明显。
三、调优效果
根据压测实际比对结果,在相同的1000用户及200多笔/秒压力下,优化之前,数据库CPU使用率高达83.29%,优化之后降至24.26%。





