oracle中,为什么order by的字段要放在联合索引的最后?
严格来说没有放到最后的说法. 有几种情况:
1.如果经过where条件过滤后返回的结果集比较小, 索引不包含order by字段, 做个排序也没关系;
2.如果过滤条件都是等值条件,而且返回的结果集有点大, 为了避免排序, order by字段确实是放到最后;
3.如果过滤条件含有非等值条件, 比如>,< , like , <> 等, 这个时候order by 字段就不是最后,而是非等值条件放到最后(减少回表) , 这种组合索引的创建原理叫ESR(equal,sort,range)理论.
4. 如果返回列较少,可以再把返回列加上,,成ESRR,那就是在组合索引的最后增加返回列. 形成覆盖索引, 能进一步减少回表.
具体使用什么样的索引, 归根结底还是要根据表上各字段的数据分布决定.
评论
有用 1
由于索引是有序的,对于一个组合索引(a,b,c),首先是按a排序,在a相同的情况下,按b排序,在a,b都相同的情况下,按c排序。再一个查询中where a=1and b=2 order by c。这个时候记录是按c排序的,可以利用索引的有序性,直接返回记录,无需再进行排序。
评论
有用 3首先联合索引中的各列都是排序的,前导列和后面的where中的过虑掉数据,过滤后留下的数据就是需要的数据,因为order by已经在索引中排序,这样就利用索引消除了排序。有时为了减少回表,会将select后的列放在索引最后。
评论
有用 2对此我有点疑惑:
create table t (c1 varchar2(10),c2 varchar2(10),c3 varchar2(10));
insert into t values ('a','b','h');
insert into t values ('x','y','a');
insert into t values ('a','b','c');
commit;
create index idx_t on t(c1,c2,c3);
那么idx_t索引内容应该如下
a b c 第三行rowid
a b h 第一行rowid
x y a 第二行rowid
select * from t where c1='a' and c2='b' order by c3;
那么filter时走索引idx_t,因为c3是联合索引的后部列,所以filter后的次序就是按c3排序的,无须再排序。
drop index idx_t;
create index idx_r on t(c3,c1,c2);
那么idx_r索引内容应该如下
x y a 第二行rowid
a b c 第三行rowid
a b h 第一行rowid
select * from t where c1='a' and c2='b' order by c3;
那么filter时仍走索引idx_r, 因为c3是联合索引的前导列,所以filter后的次序就是按c3排序的,也无须再排序。
既然两种情况都可以省略掉排序这步,为什么说c3列必须在联合索引的后部?
评论
有用 1第二种有回表?我没看出来啊。如果有,应该有access table by rowid字样,可是第二种的执行计划里并没有啊。
评论
有用 0
墨值悬赏

