暂无图片
组合索引问题
我来答
分享
lu9up的数据库笔记
2023-09-19
组合索引问题

oracle中,为什么order by的字段要放在联合索引的最后?

我来答
添加附件
收藏
分享
问题补充
6条回答
默认
最新
广州_老虎刘

严格来说没有放到最后的说法. 有几种情况:

1.如果经过where条件过滤后返回的结果集比较小, 索引不包含order by字段, 做个排序也没关系; 

2.如果过滤条件都是等值条件,而且返回的结果集有点大, 为了避免排序, order by字段确实是放到最后; 

3.如果过滤条件含有非等值条件, 比如>,< , like , <> 等, 这个时候order by 字段就不是最后,而是非等值条件放到最后(减少回表) , 这种组合索引的创建原理叫ESR(equal,sort,range)理论. 

4. 如果返回列较少,可以再把返回列加上,,成ESRR,那就是在组合索引的最后增加返回列.  形成覆盖索引, 能进一步减少回表.    

具体使用什么样的索引, 归根结底还是要根据表上各字段的数据分布决定.

暂无图片 评论
暂无图片 有用 1
打赏 1
暂无图片
lu9up的数据库笔记
题主
2023-09-19
大佬,能解释一下原理吗?
lnn

提高查询性能,减少排序操作开销

暂无图片 评论
暂无图片 有用 4
打赏 0
张sir

由于索引是有序的,对于一个组合索引(a,b,c),首先是按a排序,在a相同的情况下,按b排序,在a,b都相同的情况下,按c排序。再一个查询中where a=1and b=2 order by c。这个时候记录是按c排序的,可以利用索引的有序性,直接返回记录,无需再进行排序。

暂无图片 评论
暂无图片 有用 3
打赏 0
Rocky

首先联合索引中的各列都是排序的,前导列和后面的where中的过虑掉数据,过滤后留下的数据就是需要的数据,因为order by已经在索引中排序,这样就利用索引消除了排序。有时为了减少回表,会将select后的列放在索引最后。

暂无图片 评论
暂无图片 有用 2
打赏 0
Thomas

对此我有点疑惑:

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
打赏 0
lu9up的数据库笔记
题主
2023-09-19
第一种c3列在组合索引后面情况,我试了一下是不用回表做filter的: -------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 2 | 42 | 1 (0)| 00:00:01 | |* 1 | INDEX RANGE SCAN| IDX_T | 2 | 42 | 1 (0)| 00:00:01 | -------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - access("C1"='a' AND "C2"='b') 第二种c3列为引导列,有回表: -------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 2 | 42 | 1 (0)| 00:00:01 | |* 1 | INDEX FULL SCAN | IDX_R | 2 | 42 | 1 (0)| 00:00:01 | -------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - access("C1"='a' AND "C2"='b') filter("C1"='a' AND "C2"='b')
Thomas

第二种有回表?我没看出来啊。如果有,应该有access table by rowid字样,可是第二种的执行计划里并没有啊。

暂无图片 评论
暂无图片 有用 0
打赏 0
Rocky
2023-09-21
第二个是走index full scan 你可以再这个表多加几列并且设置成char类型 将表数据加到百万以上,实际上就是创造一个大表 再观察下结果 是不是变成TABLE ACCESS FULL + SORT ORDER BY 但是如果返回数据量较少的情况下,还是可以走第一个索引的
回答交流
Markdown


请输入正文
提交
相关推荐
oracle 11.2.0.4版本 win环境,生成awr报告停止不动
回答 2
已采纳
这是一个已知问题。原因是新库没有统计信息,其中一个SQL的执行计划出现问题。收集一下统计信息即可。
Oracle打印表结构成Excel
回答 1
表结构查dbatabcols,表字段注释查dbatabcomments,然后写个sql关联这两个表就是表结构的表格,再用工具比如plsqldeveloper导出成excel文件
12cpdb无法启动,也无法删除
回答 3
alert日志看了吗?贴一下看看
10053,10046 看这个样子有1000多个事件可以跟踪是不是?
回答 1
已采纳
1005310046都是主要针对特定的sql进行分析的,10046是执行过程分析,10053是执行计划产生的分析
windows2019能装oracle11g吗?
回答 1
oracle11g没有windowsserver2019的认证CertifiedWithOperatingSystems(13Items)MicrosoftWindowsx64(64bit)11Ver
需要用到Oracle里v$osstat这个视图,需要测试几个版本的Oracle,但9i里没有这个视图,请问怎么处理?
回答 1
😂,没有就用不了了,还能怎么处理。不过你可以参考下这篇,看着应该可以:https://blog.csdn.net/weixin30591519/article/details/116507531
数据泵导入的时候如何导入触发器
回答 1
这个问题主要是导入的触发器定义引入的表的问题,因此源schema都导入到目标用户,因而报错。利用DDL抽取到所有的触发器,批量修改用户即可。
使用toad for oracle 连接远程数据库时报错:ORA-12660 加密或加密校验和参数不兼容
回答 2
你尝试把你本地的ORACLE客户端换成更高版本的试试(就是那个instantclient文件夹,带oci.dll和tnsnames.ora的),如果是低版本客户端连高版本数据库的时候,就会报这个,因为
dba_data_files 与 v$datafile
回答 1
已采纳
V$DATAFILE,描述控制文件中记录的数据文件状态,是个动态视图,在数据库运行时是会不断进行更新的DBADATAFILES,描述数据字典中记录的数据文件状态,是个静态视图,2个视图记录的数据文件信
Oracle的双击热备是不是比装Rac简单很多
回答 1
双机热备是什么?如果问我,我觉得rac简单多了