您好,欢迎访问一九零五行业门户网

如何访问索引最大最小值min/max scan

访问索引的最大和最小值,oracle做了哪些优化呢?不同的版本是否有限制呢?索引是有序存储的,因此,获取索引的最大值,只需要扫描最右(最左desc索引)叶子块,最小值,只需要扫描最左(最右desc索引)叶子块即可,在rbo中就有这种优化访问路径了。见下
访问索引的最大和最小值,oracle做了哪些优化呢?不同的版本是否有限制呢?索引是有序存储的,因此,获取索引的最大值,只需要扫描最右(最左desc索引)叶子块,最小值,只需要扫描最左(最右desc索引)叶子块即可,在rbo中就有这种优化访问路径了。见下图(摘自oracle 11g concepts):
如下例:
单独访问max,min,可以走index full scan min/max访问路径
dingjun123@oradb> show rel
release 1102000100drop table t;
create table t as select * from dba_objects;
create index idx_t on t(object_id);
dingjun123@oradb> select max(object_id) from t;
1 row selected.
execution plan
———————————————————-
plan hash value: 3689784082
————————————————————————————
| id ?| operation ? ? ? ? ? ? ? ? ?| name ?| rows ?| bytes | cost (%cpu)| time ? ? |
————————————————————————————
| ? 0 | select statement ? ? ? ? ? | ? ? ? | ? ? 1 | ? ?13 | ? ? 2 ? (0)| 00:00:01 |
| ? 1 | ?sort aggregate ? ? ? ? ? ?| ? ? ? | ? ? 1 | ? ?13 | ? ? ? ? ? ?| ? ? ? ? ?|
| ? 2 | index full scan (min/max)| idx_t | ? ? 1 | ? ?13 | ? ? 2 ? (0)| 00:00:01 |
————————————————————————————
note
—–
? ?- dynamic sampling used for this statement (level=2)
statistics
———————————————————-
? ? ? ? ? 0 ?recursive calls
? ? ? ? ? 0 ?db block gets
? ? ? ? ? 2 ?consistent gets
? ? ? ? ? 0 ?physical reads
? ? ? ? ? 0 ?redo size
? ? ? ? 430 ?bytes sent via sql*net to client
? ? ? ? 415 ?bytes received via sql*net from client
? ? ? ? ? 2 ?sql*net roundtrips to/from client
? ? ? ? ? 0 ?sorts (memory)
? ? ? ? ? 0 ?sorts (disk)
? ? ? ? ? 1 ?rows processed
dingjun123@oradb> select min(object_id) from t;
1 row selected.
execution plan
———————————————————-
plan hash value: 3689784082
————————————————————————————
| id ?| operation ? ? ? ? ? ? ? ? ?| name ?| rows ?| bytes | cost (%cpu)| time ? ? |
————————————————————————————
| ? 0 | select statement ? ? ? ? ? | ? ? ? | ? ? 1 | ? ?13 | ? ? 2 ? (0)| 00:00:01 |
| ? 1 | ?sort aggregate ? ? ? ? ? ?| ? ? ? | ? ? 1 | ? ?13 | ? ? ? ? ? ?| ? ? ? ? ?|
| ? 2 | index full scan (min/max)| idx_t | ? ? 1 | ? ?13 | ? ? 2 ? (0)| 00:00:01 |
————————————————————————————
note
—–
? ?- dynamic sampling used for this statement (level=2)
statistics
———————————————————-
? ? ? ? ? 0 ?recursive calls
? ? ? ? ? 0 ?db block gets
? ? ? ? ? 2 ?consistent gets
? ? ? ? ? 0 ?physical reads
? ? ? ? ? 0 ?redo size
? ? ? ? 428 ?bytes sent via sql*net to client
? ? ? ? 415 ?bytes received via sql*net from client
? ? ? ? ? 2 ?sql*net roundtrips to/from client
? ? ? ? ? 0 ?sorts (memory)
? ? ? ? ? 0 ?sorts (disk)
? ? ? ? ? 1 ?rows processed
通过这种高效的访问路径,只需要扫描最左或最右边的一个叶子块即可,只找1行数据,上面统计信息显示只需要2个io就搞定了。如果要一条sql同时获得min/max呢?
–先收集统计信息
dingjun123@oradb> exec dbms_stats.gather_table_stats(ownname => user,tabname => ‘t’,estimate_percent => 100,cascade => true);
pl/sql procedure successfully completed.?
dingjun123@oradb> select max(object_id) max_obj,min(object_id) min_obj from t;
1 row selected.
execution plan
———————————————————-
plan hash value: 2966233522
—————————————————————————
| id ?| operation ? ? ? ? ?| name | rows ?| bytes | cost (%cpu)| time ? ? |
—————————————————————————
| ? 0 | select statement ? | ? ? ?| ? ? 1 | ? ?13 | ? 299 ? (1)| 00:00:04 |
| ? 1 | ?sort aggregate ? ?| ? ? ?| ? ? 1 | ? ?13 | ? ? ? ? ? ?| ? ? ? ? ?|
| ? 2 | table access full| t ? ?| 75885 | ? 963k| ? 299 ? (1)| 00:00:04 |
—————————————————————————
? ? 竟然走的全表扫描,很显然,我这里的索引,是比表小很多,应该只访问索引就可以了,虽然object_id无not null约束,但是max/min(列)运算已经告之oracle,这里肯定不包含null,但是:
dingjun123@oradb> select max(object_id) max_obj,min(object_id) min_obj from t?where object_id is not null;
1 row selected.execution plan
———————————————————-
plan hash value: 2371838348
——————————————————————————-
| id ?| operation ? ? ? ? ? ? | name ?| rows ?| bytes | cost (%cpu)| time ? ? |
——————————————————————————-
| ? 0 | select statement ? ? ?| ? ? ? | ? ? 1 | ? ? 5 | ? ?48 ? (3)| 00:00:01 |
| ? 1 | ?sort aggregate ? ? ? | ? ? ? | ? ? 1 | ? ? 5 | ? ? ? ? ? ?| ? ? ? ? ?|
|* ?2 | index fast full scan| idx_t | 75263 | ? 367k| ? ?48 ? (3)| 00:00:01 |
——————————————————————————-
predicate information (identified by operation id):
—————————————————
? ?2 – filter(“object_id” is not null)
? ? 显式加where object_id is not null告诉oracle,那么计划改变,走index fast full scan,这是正确的。这可以认定是此版本下oracle优化器的一个限制。通过实验发现,单个组函数对索引运算,可以走索引,但是2个或以上的就不行了。
–单个组函数对索引运算,走索引
dingjun123@oradb> select sum(object_id) ?from t;
execution plan
———————————————————-
plan hash value: 2371838348
——————————————————————————-
| id ?| operation ? ? ? ? ? ? | name ?| rows ?| bytes | cost (%cpu)| time ? ? |
——————————————————————————-
| ? 0 | select statement ? ? ?| ? ? ? | ? ? 1 | ? ? 5 | ? ?48 ? (3)| 00:00:01 |
| ? 1 | ?sort aggregate ? ? ? | ? ? ? | ? ? 1 | ? ? 5 | ? ? ? ? ? ?| ? ? ? ? ?|
| ? 2 | index fast full scan| idx_t | 75264 | ? 367k| ? ?48 ? (3)| 00:00:01 |
——————————————————————————-–多个组函数对索引运算,不走索引,需要not null约束或手动加is not null条件
dingjun123@oradb> select sum(object_id) ?,count(object_id) from t ;
execution plan
———————————————————-
plan hash value: 2966233522
—————————————————————————
| id ?| operation ? ? ? ? ?| name | rows ?| bytes | cost (%cpu)| time ? ? |
—————————————————————————
| ? 0 | select statement ? | ? ? ?| ? ? 1 | ? ? 5 | ? 299 ? (1)| 00:00:04 |
| ? 1 | ?sort aggregate ? ?| ? ? ?| ? ? 1 | ? ? 5 | ? ? ? ? ? ?| ? ? ? ? ?|
| ? 2 | table access full| t ? ?| 75264 | ? 367k| ? 299 ? (1)| 00:00:04 |
—————————————————————————
–无not null,使用hint也是失效的
dingjun123@oradb> select/*+index(t)*/ sum(object_id) ?,count(object_id) from t ;
execution plan
———————————————————-
plan hash value: 2966233522
—————————————————————————
| id ?| operation ? ? ? ? ?| name | rows ?| bytes | cost (%cpu)| time ? ? |
—————————————————————————
| ? 0 | select statement ? | ? ? ?| ? ? 1 | ? ? 5 | ? 299 ? (1)| 00:00:04 |
| ? 1 | ?sort aggregate ? ?| ? ? ?| ? ? 1 | ? ? 5 | ? ? ? ? ? ?| ? ? ? ? ?|
| ? 2 | table access full| t ? ?| 75264 | ? 367k| ? 299 ? (1)| 00:00:04 |
—————————————————————————
?
dingjun123@oradb> select sum(object_id) ?,count(object_id) from t?where object_id is not null;
execution plan
———————————————————-
plan hash value: 2371838348
——————————————————————————-
| id ?| operation ? ? ? ? ? ? | name ?| rows ?| bytes | cost (%cpu)| time ? ? |
——————————————————————————-
| ? 0 | select statement ? ? ?| ? ? ? | ? ? 1 | ? ? 5 | ? ?48 ? (3)| 00:00:01 |
| ? 1 | ?sort aggregate ? ? ? | ? ? ? | ? ? 1 | ? ? 5 | ? ? ? ? ? ?| ? ? ? ? ?|
|* ?2 | index fast full scan| idx_t | 75263 | ? 367k| ? ?48 ? (3)| 00:00:01 |
——————————————————————————-
predicate information (identified by operation id):
—————————————————
? ?2 – filter(“object_id” is not null)
–多个组函数实验,省略,当然多个组函数
? ? 那么这种情况下,oracle为什么不走index full?min/max呢,很显然select min,max… from 是不行的。可以转换一下思路:既然单个组函数操作,可以走索引,特别是min,max的操作,可以高效走index full min,max,那么就可以使用2条sql,然后合并即可:
–使用union all,缺点,不能直接知道谁大谁小,还得进一步运算
–访问2次索引,使用的都是full min/max路径,因此io增加1倍,4个io
dingjun123@oradb> select min(object_id) from t
? 2 ?union all
? 3 ?select max(object_id) from t;2 rows selected.
execution plan
———————————————————-
plan hash value: 2039144771
————————————————————————————-
| id ?| operation ? ? ? ? ? ? ? ? ? | name ?| rows ?| bytes | cost (%cpu)| time ? ? |
————————————————————————————-
| ? 0 | select statement ? ? ? ? ? ?| ? ? ? | ? ? 2 | ? ?10 | ? ? 4 ?(50)| 00:00:01 |
| ? 1 |union-all ? ? ? ? ? ? ? ?| ? ? ? | ? ? ? | ? ? ? | ? ? ? ? ? ?| ? ? ? ? ?|
| ? 2 | ? sort aggregate ? ? ? ? ? ?| ? ? ? | ? ? 1 | ? ? 5 | ? ? ? ? ? ?| ? ? ? ? ?|
| ? 3 | ? ?index full scan (min/max)| idx_t | ? ? 1 | ? ? 5 | ? ? 2 ? (0)| 00:00:01 |
| ? 4 | ? sort aggregate ? ? ? ? ? ?| ? ? ? | ? ? 1 | ? ? 5 | ? ? ? ? ? ?| ? ? ? ? ?|
| ? 5 | ? ?index full scan (min/max)| idx_t | ? ? 1 | ? ? 5 | ? ? 2 ? (0)| 00:00:01 |
————————————————————————————-
statistics
———————————————————-
? ? ? ? ? 0 ?recursive calls
? ? ? ? ? 0 ?db block gets
? ? ? ? ? 4 ?consistent gets
? ? ? ? ? 0 ?physical reads
? ? ? ? ? 0 ?redo size
? ? ? ? 468 ?bytes sent via sql*net to client
? ? ? ? 415 ?bytes received via sql*net from client
? ? ? ? ? 2 ?sql*net roundtrips to/from client
? ? ? ? ? 0 ?sorts (memory)
? ? ? ? ? 0 ?sorts (disk)
? ? ? ? ? 2 ?rows processed
–使用标量子查询,好处,最大哪个列是最大值,哪个列是最小值
dingjun123@oradb> select (select min(object_id) from t) min_obj,
? 2 ?(select max(object_id) from t) max_obj
? 3 ?from dual;
1 row selected.
execution plan
———————————————————-
plan hash value: 3635878085
————————————————————————————
| id ?| operation ? ? ? ? ? ? ? ? ?| name ?| rows ?| bytes | cost (%cpu)| time ? ? |
————————————————————————————
| ? 0 | select statement ? ? ? ? ? | ? ? ? | ? ? 1 | ? ? ? | ? ? 2 ? (0)| 00:00:01 |
| ? 1 | ?sort aggregate ? ? ? ? ? ?| ? ? ? | ? ? 1 | ? ? 5 | ? ? ? ? ? ?| ? ? ? ? ?|
| ? 2 | ? index full scan (min/max)| idx_t | ? ? 1 | ? ? 5 | ? ? 2 ? (0)| 00:00:01 |
| ? 3 | ?sort aggregate ? ? ? ? ? ?| ? ? ? | ? ? 1 | ? ? 5 | ? ? ? ? ? ?| ? ? ? ? ?|
| ? 4 | ? index full scan (min/max)| idx_t | ? ? 1 | ? ? 5 | ? ? 2 ? (0)| 00:00:01 |
| ? 5 | ?fast dual ? ? ? ? ? ? ? ? | ? ? ? | ? ? 1 | ? ? ? | ? ? 2 ? (0)| 00:00:01 |
————————————————————————————
statistics
———————————————————-
? ? ? ? ? 1 ?recursive calls
? ? ? ? ? 0 ?db block gets
? ? ? ? ? 4 ?consistent gets
? ? ? ? ? 0 ?physical reads
? ? ? ? ? 0 ?redo size
? ? ? ? 487 ?bytes sent via sql*net to client
? ? ? ? 415 ?bytes received via sql*net from client
? ? ? ? ? 2 ?sql*net roundtrips to/from client
? ? ? ? ? 0 ?sorts (memory)
? ? ? ? ? 0 ?sorts (disk)
? ? ? ? ? 1 ?rows processed
? ? 第一种union all方式可以行列转换一下:
dingjun123@oradb> select max(decode(rn,1,val)) min_obj, max(decode(rn,2,val)) max_obj
? 2 ?from (
? 3 ?select min(object_id) val,1 rn from t
? 4 ?union all
? 5 ?select max(object_id),2 rn from t
? 6 ?);? ?min_obj ? ?max_obj
———- ———-
? ? ? ? ?2 ? ? 108164
? ?下面举一个实例说明index full scan min/max的使用:
需求:查询出最小object_id的所有信息。用多种方法实现:
–先将object_id变为not null约束
delete from t where object_id is null;
alter table t modify object_id not null;–1.分析函数,因为object_id有索引,11g的分页函数也可以谓词推进,如果走索引可以window nosort stopkey,效率不错,5个io
dingjun123@oradb> select *
? 2 ?from (
? 3 ?select t.*,row_number() over(order by object_id) rn
? 4 ?from t
? 5 ?) where rn=1;
1 row selected.
execution plan
———————————————————-
plan hash value: 233755475
—————————————————————————————
| id ?| operation ? ? ? ? ? ? ? ? ? ? | name ?| rows ?| bytes | cost (%cpu)| time ? ? |
—————————————————————————————
| ? 0 | select statement ? ? ? ? ? ? ?| ? ? ? | 75264 | ? ?15m| ?1478 ? (1)| 00:00:18 |
|* ?1 | ?view ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? | 75264 | ? ?15m| ?1478 ? (1)| 00:00:18 |
|* ?2 | window nosort stopkey?? ? ? | ? ? ? | 75264 | ?7129k| ?1478 ? (1)| 00:00:18 |
| ? 3 | ? ?table access by index rowid| t ? ? | 75264 | ?7129k| ?1478 ? (1)| 00:00:18 |
| ? 4 | ? ? index full scan ? ? ? ? ? | idx_t | 75264 | ? ? ? | ? 169 ? (1)| 00:00:03 |
—————————————————————————————
predicate information (identified by operation id):
—————————————————
? ?1 – filter(“rn”=1)
? ?2 – filter(row_number() over ( order by “object_id”)
statistics
———————————————————-
? ? ? ? ? 0 ?recursive calls
? ? ? ? ? 0 ?db block gets
? ? ? ? 5 ?consistent gets
? ? ? ? ? 0 ?physical reads
? ? ? ? ? 0 ?redo size
? ? ? ?1451 ?bytes sent via sql*net to client
? ? ? ? 415 ?bytes received via sql*net from client
? ? ? ? ? 2 ?sql*net roundtrips to/from client
? ? ? ? ? 0 ?sorts (memory)
? ? ? ? ? 0 ?sorts (disk)
? ? ? ? ? 1 ?rows processed
–2.使用传统分页rownum,走stopkey,3个io,效率最好
dingjun123@oradb> select x.*
? 2 ?from (
? 3 ?select * from t order by object_id
? 4 ?) x where rownum=1;
1 row selected.
execution plan
———————————————————-
plan hash value: 3436459561
—————————————————————————————
| id ?| operation ? ? ? ? ? ? ? ? ? ? | name ?| rows ?| bytes | cost (%cpu)| time ? ? |
—————————————————————————————
| ? 0 | select statement ? ? ? ? ? ? ?| ? ? ? | ? ? 1 | ? 207 | ? ? 3 ? (0)| 00:00:01 |
|* ?1 | ?count stopkey ? ? ? ? ? ? ? ?| ? ? ? | ? ? ? | ? ? ? | ? ? ? ? ? ?| ? ? ? ? ?|
| ? 2 | ? view ? ? ? ? ? ? ? ? ? ? ? ?| ? ? ? | ? ? 1 | ? 207 | ? ? 3 ? (0)| 00:00:01 |
| ? 3 | ? ?table access by index rowid| t ? ? | 75264 | ?7129k| ? ? 3 ? (0)| 00:00:01 |
| ? 4 | ? ? index full scan ? ? ? ? ? | idx_t | ? ? 1 | ? ? ? | ? ? 2 ? (0)| 00:00:01 |
—————————————————————————————
predicate information (identified by operation id):
—————————————————
? ?1 – filter(rownum=1)
statistics
———————————————————-
? ? ? ? ? 0 ?recursive calls
? ? ? ? ? 0 ?db block gets
? ? ? ? 3 ?consistent gets
? ? ? ? ? 0 ?physical reads
? ? ? ? ? 0 ?redo size
? ? ? ?1392 ?bytes sent via sql*net to client
? ? ? ? 415 ?bytes received via sql*net from client
? ? ? ? ? 2 ?sql*net roundtrips to/from client
? ? ? ? ? 0 ?sorts (memory)
? ? ? ? ? 0 ?sorts (disk)
? ? ? ? ? 1 ?rows processed
–3.子查询实现,子查询走高效的full index scan?min max,外部查询条件又是object_id,走index range scan,6个io,效率比上面的差,但是不算太差
dingjun123@oradb> select * from t
? 2 ?where t.object_id=
? 3 ?(select min(object_id) from t);
1 row selected.
execution plan
———————————————————-
plan hash value: 72615852
—————————————————————————————
| id ?| operation ? ? ? ? ? ? ? ? ? ?| name ? | rows ?| bytes | cost (%cpu)| time ? ? |
—————————————————————————————
| ? 0 | select statement ? ? ? ? ? ? | ? ? ? ?| ? ? 1 | ? ?97 | ? ? 4 ? (0)| 00:00:01 |
| ? 1 | ?table access by index rowid | t ? ? ?| ? ? 1 | ? ?97 | ? ? 2 ? (0)| 00:00:01 |
|* ?2 | ? index range scan ? ? ? ? ? | idx_t ?| ? ? 1 | ? ? ? | ? ? 1 ? (0)| 00:00:01 |
| ? 3 | ? ?sort aggregate ? ? ? ? ? ?| ? ? ? ?| ? ? 1 | ? ? 5 | ? ? ? ? ? ?| ? ? ? ? ?|
| ? 4 | ? ? index full scan (min/max)| idx1_t | ? ? 1 | ? ? 5 | ? ? 2 ? (0)| 00:00:01 |
—————————————————————————————
predicate information (identified by operation id):
————————————————–
? ?2 – access(“t”.”object_id”= (select min(“object_id”) from “t” “t”))
statistics
———————————————————-
? ? ? ? ? 0 ?recursive calls
? ? ? ? ? 0 ?db block gets
? ? ? ? 6 ?consistent gets
? ? ? ? ? 0 ?physical reads
? ? ? ? ? 0 ?redo size
? ? ? ?1392 ?bytes sent via sql*net to client
? ? ? ? 415 ?bytes received via sql*net from client
? ? ? ? ? 2 ?sql*net roundtrips to/from client
? ? ? ? ? 0 ?sorts (memory)
? ? ? ? ? 0 ?sorts (disk)
? ? ? ? ? 1 ?rows processed
? ? 当然,如果要同时找最大最小值索引的全部信息:
–不能图方便,不是简单的sql就是好的sql,无法走stop key和降序索引扫描,逻辑读1474
dingjun123@oradb> select *
? 2 ?from (
? 3 ?select t.*,row_number() over(order by object_id) rn1,
? 4 ?row_number() over(order by object_id desc) rn2
? 5 ?from t
? 6 ?) where rn1=1 or rn2=1;
2 rows selected.execution plan
———————————————————-
plan hash value: 1020799068
————————————————————————————————
| id ?| operation ? ? ? ? ? ? ? ? ? ? ?| name ?| rows ?| bytes |tempspc| cost (%cpu)| time ? ? |
————————————————————————————————
| ? 0 | select statement ? ? ? ? ? ? ? | ? ? ? | 75264 | ? ?16m| ? ? ? | ?3149 ? (1)| 00:00:38 |
|* ?1 | ?view ? ? ? ? ? ? ? ? ? ? ? ? ?| ? ? ? | 75264 | ? ?16m| ? ? ? | ?3149 ? (1)| 00:00:38 |
| ? 2 | ? window sort ? ? ? ? ? ? ? ? ?| ? ? ? | 75264 | ?7129k| ?9880k| ?3149 ? (1)| 00:00:38 |
| ? 3 | ? ?window nosort ? ? ? ? ? ? ? | ? ? ? | 75264 | ?7129k| ? ? ? | ?3149 ? (1)| 00:00:38 |
| ? 4 | ? ? table access by index rowid| t ? ? | 75264 | ?7129k| ? ? ? | ?1478 ? (1)| 00:00:18 |
| ? 5 | ? ? ?index full scan ? ? ? ? ? | idx_t | 75264 | ? ? ? | ? ? ? | ? 169 ? (1)| 00:00:03 |
————————————————————————————————
predicate information (identified by operation id):
—————————————————
? ?1 – filter(“rn1″=1 or “rn2″=1)
statistics
———————————————————-
? ? ? ? ? 0 ?recursive calls
? ? ? ? ? 0 ?db block gets
? ? ?1474 ?consistent gets
? ? ? ? ? 0 ?physical reads
? ? ? ? ? 0 ?redo size
? ? ? ?1639 ?bytes sent via sql*net to client
? ? ? ? 415 ?bytes received via sql*net from client
? ? ? ? ? 2 ?sql*net roundtrips to/from client
? ? ? ? ? 1 ?sorts (memory)
? ? ? ? ? 0 ?sorts (disk)
? ? ? ? ? 2 ?rows processed
–使用union all,两条语句都很高效,后面的可以走desc扫描并stop key,逻辑读8
dingjun123@oradb> select *
? 2 ?from (
? 3 ?select t.*,row_number() over(order by object_id) rn
? 4 ?from t
? 5 ?) where rn=1
? 6 ?union all
? 7 ?select *
? 8 ?from (
? 9 ?select t.*,row_number() over(order by object_id desc) rn
?10 ?from t
?11 ?) where rn=1;
2 rows selected.
execution plan
———————————————————-
plan hash value: 4213848416
—————————————————————————————-
| id ?| operation ? ? ? ? ? ? ? ? ? ? ?| name ?| rows ?| bytes | cost (%cpu)| time ? ? |
—————————————————————————————-
| ? 0 | select statement ? ? ? ? ? ? ? | ? ? ? | ? 150k| ? ?31m| ?2955 ?(51)| 00:00:36 |
| ? 1 | ?union-all ? ? ? ? ? ? ? ? ? ? | ? ? ? | ? ? ? | ? ? ? | ? ? ? ? ? ?| ? ? ? ? ?|
|* ?2 | ? view ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? | 75264 | ? ?15m| ?1478 ? (1)| 00:00:18 |
|* ?3 | ? ?window nosort stopkey ? ? ? | ? ? ? | 75264 | ?7129k| ?1478 ? (1)| 00:00:18 |
| ? 4 | ? ? table access by index rowid| t ? ? | 75264 | ?7129k| ?1478 ? (1)| 00:00:18 |
| ? 5 | ? ? ?index full scan ? ? ? ? ? | idx_t | 75264 | ? ? ? | ? 169 ? (1)| 00:00:03 |
|* ?6 | ? view ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? | 75264 | ? ?15m| ?1478 ? (1)| 00:00:18 |
|* ?7 | ? ?window nosort stopkey ? ? ? | ? ? ? | 75264 | ?7129k| ?1478 ? (1)| 00:00:18 |
| ? 8 | ? ? table access by index rowid| t ? ? | 75264 | ?7129k| ?1478 ? (1)| 00:00:18 |
| ? 9 | ? ? ?index full scan descending| idx_t | 75264 | ? ? ? | ? 169 ? (1)| 00:00:03 |
—————————————————————————————-
predicate information (identified by operation id):
—————————————————
? ?2 – filter(“rn”=1)
? ?3 – filter(row_number() over ( order by “object_id”)
? ?6 – filter(“rn”=1)
? ?7 – filter(row_number() over ( order by internal_function(“object_id”) desc
? ? ? ? ? ? ? )
statistics
———————————————————-
? ? ? ? ? 0 ?recursive calls
? ? ? ? ? 0 ?db block gets
? ? ? ? 8 ?consistent gets
? ? ? ? ? 0 ?physical reads
? ? ? ? ? 0 ?redo size
? ? ? ?1571 ?bytes sent via sql*net to client
? ? ? ? 415 ?bytes received via sql*net from client
? ? ? ? ? 2 ?sql*net roundtrips to/from client
? ? ? ? ? 0 ?sorts (memory)
? ? ? ? ? 0 ?sorts (disk)
? ? ? ? ? 2 ?rows processed
–传统rownum分页union all,效率最好,逻辑读6
dingjun123@oradb> select x.*
? 2 ?from (
? 3 ?select * from t order by object_id
? 4 ?) x where rownum=1
? 5 ?union all
? 6 ?select x.*
? 7 ?from (
? 8 ?select * from t order by object_id desc
? 9 ?) x where rownum=1;
2 rows selected.
execution plan
———————————————————-
plan hash value: 1989929593
—————————————————————————————-
| id ?| operation ? ? ? ? ? ? ? ? ? ? ?| name ?| rows ?| bytes | cost (%cpu)| time ? ? |
—————————————————————————————-
| ? 0 | select statement ? ? ? ? ? ? ? | ? ? ? | ? ? 2 | ? 414 | ?2955 ?(51)| 00:00:36 |
| ? 1 | ?union-all ? ? ? ? ? ? ? ? ? ? | ? ? ? | ? ? ? | ? ? ? | ? ? ? ? ? ?| ? ? ? ? ?|
|* ?2 | ? count stopkey ? ? ? ? ? ? ? ?| ? ? ? | ? ? ? | ? ? ? | ? ? ? ? ? ?| ? ? ? ? ?|
| ? 3 | ? ?view ? ? ? ? ? ? ? ? ? ? ? ?| ? ? ? | 75264 | ? ?14m| ?1478 ? (1)| 00:00:18 |
| ? 4 | ? ? table access by index rowid| t ? ? | 75264 | ?7129k| ?1478 ? (1)| 00:00:18 |
| ? 5 | ? ? ?index full scan ? ? ? ? ? | idx_t | 75264 | ? ? ? | ? 169 ? (1)| 00:00:03 |
|* ?6 | ? count stopkey ? ? ? ? ? ? ? ?| ? ? ? | ? ? ? | ? ? ? | ? ? ? ? ? ?| ? ? ? ? ?|
| ? 7 | ? ?view ? ? ? ? ? ? ? ? ? ? ? ?| ? ? ? | 75264 | ? ?14m| ?1478 ? (1)| 00:00:18 |
| ? 8 | ? ? table access by index rowid| t ? ? | 75264 | ?7129k| ?1478 ? (1)| 00:00:18 |
| ? 9 | ? ? ?index full scan descending| idx_t | 75264 | ? ? ? | ? 169 ? (1)| 00:00:03 |
—————————————————————————————-
predicate information (identified by operation id):
—————————————————
? ?2 – filter(rownum=1)
? ?6 – filter(rownum=1)
statistics
———————————————————-
? ? ? ? ? 0 ?recursive calls
? ? ? ? ? 0 ?db block gets
? ? ? ? 6 ?consistent gets
? ? ? ? ? 0 ?physical reads
? ? ? ? ? 0 ?redo size
? ? ? ?1509 ?bytes sent via sql*net to client
? ? ? ? 415 ?bytes received via sql*net from client
? ? ? ? ? 2 ?sql*net roundtrips to/from client
? ? ? ? ? 0 ?sorts (memory)
? ? ? ? ? 0 ?sorts (disk)
? ? ? ? ? 2 ?rows processed
–使用min,max扫描,并且子查询走索引,逻辑读11,虽然不及前2个,但是还不错,并且sql简单
dingjun123@oradb> select * from t
? 2 ?where t.object_id in
? 3 ?(select min(object_id) from t union all
? 4 ? select max(object_id) from t);
2 rows selected.
execution plan
———————————————————-
plan hash value: 4243345848
——————————————————————————————–
| id ?| operation ? ? ? ? ? ? ? ? ? ? ? | name ? ? | rows ?| bytes | cost (%cpu)| time ? ? |
——————————————————————————————–
| ? 0 | select statement ? ? ? ? ? ? ? ?| ? ? ? ? ?| ? ? 2 | ? 220 | ? ? 8 ? (0)| 00:00:01 |
| ? 1 | ?nested loops ? ? ? ? ? ? ? ? ? | ? ? ? ? ?| ? ? ? | ? ? ? | ? ? ? ? ? ?| ? ? ? ? ?|
| ? 2 | ? nested loops ? ? ? ? ? ? ? ? ?| ? ? ? ? ?| ? ? 2 | ? 220 | ? ? 8 ? (0)| 00:00:01 |
| ? 3 | ? ?view ? ? ? ? ? ? ? ? ? ? ? ? | vw_nso_1 | ? ? 2 | ? ?26 | ? ? 4 ? (0)| 00:00:01 |
| ? 4 | ? ? hash unique ? ? ? ? ? ? ? ? | ? ? ? ? ?| ? ? 2 | ? ?10 | ? ? 4 ?(50)| 00:00:01
其它类似信息

推荐信息