索引是有顺序的,如果一个查询使用索引,可以利用索引的顺序读取数据,这样可以消除OrderBy的排序。
前提:索引列的顺序和OrderBy的顺序完全一致
实验使用Hr模式的Employees表,查询某个工种(job_id)的所有员工,并且按照入职时间降序排列。查看索引对排序的影响。
![](//img.blog.itpub.net/blog/attachment/201401/4/29254281_138882309631YX.png?x-oss-process=style/bb)
单独给Job_id列创建索引,则结果如下(SORT ORDER BY不能避免)
![](//img.blog.itpub.net/blog/attachment/201401/4/29254281_1388823356lLzr.png?x-oss-process=style/bb)
2.查询工种(Job_id)为IT_PROG的员工,并且按照入职时间降序排列。
可以看到,单一的Job_id作为过滤条件,也可以使用排序消除的特性
![](//img.blog.itpub.net/blog/attachment/201401/4/29254281_1388823697e05F.png?x-oss-process=style/bb)
3.查询工种(Job_id)为IT_PROG的员工,并且按照入职时间升序排列。
使用单一的Job_id作为过滤条件,甚至升序排列,也能够做到排序消除(INDEX RANGE SCAN DESCENDING)
![](//img.blog.itpub.net/blog/attachment/201401/4/29254281_1388823940Bfj5.png?x-oss-process=style/bb)
4.查看job_id为IT_PROG和ST_MAN的员工,按照工种(Job_id),入职时间(Hire_date)升序排列
![](//img.blog.itpub.net/blog/attachment/201401/4/29254281_1388824137wNxe.png?x-oss-process=style/bb)
可以看到,这种情况下,索引不能消除排序。
总结
创建A、B列的组合索引,create index ind_test on test(a,b desc)
order by a,b desc 可以消除排序
但是order by a,b 则不能消除排序。
如果a作为单独的过滤条件,则order by b 或者 order by b desc 都是可以消除排序的。
前提:索引列的顺序和OrderBy的顺序完全一致
实验使用Hr模式的Employees表,查询某个工种(job_id)的所有员工,并且按照入职时间降序排列。查看索引对排序的影响。
create table test as select * from hr.employees;
create index ind_test on test(job_id,hire_date desc);
exec dbms_stats.gather_schema_stats('EDMOND');
1.查看job_id为IT_PROG和ST_MAN的员工,按照工种(Job_id),入职时间(Hire_date)降序排列create index ind_test on test(job_id,hire_date desc);
exec dbms_stats.gather_schema_stats('EDMOND');
select * from test
where job_id='IT_PROG' or job_id='ST_MAN'
order by job_id,hire_date desc;
可以看到根据索引的顺序读取数据,消除了OrderBy排序where job_id='IT_PROG' or job_id='ST_MAN'
order by job_id,hire_date desc;
![](http://img.blog.itpub.net/blog/attachment/201401/4/29254281_138882309631YX.png?x-oss-process=style/bb)
单独给Job_id列创建索引,则结果如下(SORT ORDER BY不能避免)
![](http://img.blog.itpub.net/blog/attachment/201401/4/29254281_1388823356lLzr.png?x-oss-process=style/bb)
2.查询工种(Job_id)为IT_PROG的员工,并且按照入职时间降序排列。
可以看到,单一的Job_id作为过滤条件,也可以使用排序消除的特性
select * from test
where job_id='IT_PROG'
order by hire_date desc;
where job_id='IT_PROG'
order by hire_date desc;
![](http://img.blog.itpub.net/blog/attachment/201401/4/29254281_1388823697e05F.png?x-oss-process=style/bb)
3.查询工种(Job_id)为IT_PROG的员工,并且按照入职时间升序排列。
使用单一的Job_id作为过滤条件,甚至升序排列,也能够做到排序消除(INDEX RANGE SCAN DESCENDING)
![](http://img.blog.itpub.net/blog/attachment/201401/4/29254281_1388823940Bfj5.png?x-oss-process=style/bb)
4.查看job_id为IT_PROG和ST_MAN的员工,按照工种(Job_id),入职时间(Hire_date)升序排列
select * from test
where job_id='IT_PROG' or job_id='ST_MAN'
order by job_id,hire_date;
where job_id='IT_PROG' or job_id='ST_MAN'
order by job_id,hire_date;
![](http://img.blog.itpub.net/blog/attachment/201401/4/29254281_1388824137wNxe.png?x-oss-process=style/bb)
可以看到,这种情况下,索引不能消除排序。
总结
创建A、B列的组合索引,create index ind_test on test(a,b desc)
order by a,b desc 可以消除排序
但是order by a,b 则不能消除排序。
如果a作为单独的过滤条件,则order by b 或者 order by b desc 都是可以消除排序的。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29254281/viewspace-1067134/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/29254281/viewspace-1067134/