19.读书笔记收获不止Oracle之 索引MAX和MIN优化

前端之家收集整理的这篇文章主要介绍了19.读书笔记收获不止Oracle之 索引MAX和MIN优化前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

19.读书笔记收获不止Oracle之 索引MAX和MIN优化

1. 示例一

sql> drop table t purge;

sql> create table t as select * fromdba_objects;

sql> create index idx1_object_id on t(object_id);

使用MAX看看,能不能用到索引。

set autotrace traceonly;

set timing on;

select max(object_id) from t;

Elapsed: 00:00:00.02

Execution Plan

----------------------------------------------------------

Plan hash value: 692082706

---------------------------------------------------------------------------------------------

| Id| Operation | Name | Rows| Bytes | Cost (%cpu)| Time |

---------------------------------------------------------------------------------------------

| 0| SELECT STATEMENT | | 1 | 5 | 2(0)| 00:00:01 |

| 1| SORT AGGREGATE | | 1 | 5 | | |

| 2| INDEX FULL SCAN (MIN/MAX)| IDX1_OBJECT_ID | 1 | 5 | 2(0)| 00:00:01 |

---------------------------------------------------------------------------------------------

Statistics

----------------------------------------------------------

1recursive calls

0 dbblock gets

2consistent gets

1physical reads

0 redosize

550 bytes sent via sql*Net to client

551 bytes received via sql*Net from client

2sql*Net roundtrips to/from client

0sorts (memory)

0sorts (disk)

1 rowsprocessed

使用了索引。

其实SUM/AVG等聚合查询必须要列为空方可用到索引;MAX/MIN时无论列是否为空都可以用到索引。

2. MAX/MIN

在INDEX FULL SCAN(MIN/MAX)时,MAX取值只需要往最右边的叶子块去瞧一瞧就行了。

MAX取值一定在最右边的块上。

MIN取值,往最左边的块里去看一眼就好了,块里的第一行记录就是。

INDEX FULL SCAN就是这个思路。

无论记录如何增大,INDEX FULL SCAN (MIN/MAX)速度都基本不变。如果对查询的列没有做索引,那么该速度将会非常慢。

3. MAX/MIN性能陷阱

Selectmin(object_id),max(object_id) from t;

Elapsed:00:00:00.22

Execution Plan

----------------------------------------------------------

Plan hash value:2966233522

---------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%cpu)| Time |

---------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 5 |429 (1)| 00:00:01 |

| 1 |SORT AGGREGATE | | 1 | 5| | |

| 2 | TABLE ACCESS FULL| T |91717 | 447K| 429(1)| 00:00:01 |

---------------------------------------------------------------------------

Statistics

----------------------------------------------------------

42recursive calls

0 db block gets

1564consistent gets

1539physical reads

0 redo size

629bytes sent via sql*Net to client

551bytes received via sql*Net from client

2 sql*Net roundtrips to/fromclient

3 sorts (memory)

0 sorts (disk)

1 rows processed

进行了全表扫描。

增加is not null看看

sql> Select min(object_id),max(object_id) from t where object_idis not null;

Elapsed: 00:00:00.05

Execution Plan

----------------------------------------------------------

Plan hash value: 1296839119

----------------------------------------------------------------------------------------

| Id| Operation | Name | Rows| Bytes | Cost (%cpu)| Time |

----------------------------------------------------------------------------------------

| 0| SELECT STATEMENT | |1 | 5 | 57 (0)| 00:00:01 |

| 1| SORT AGGREGATE | |1 | 5 | | |

|* 2| INDEX FAST FULL SCAN| IDX1_OBJECT_ID | 91717| 447K| 57 (0)| 00:00:01 |

----------------------------------------------------------------------------------------

Predicate Information (identified byoperation id):

---------------------------------------------------

2- filter("OBJECT_ID" IS NOT NULL)

Statistics

----------------------------------------------------------

1recursive calls

0 dbblock gets

211 consistent gets

202 physical reads

0 redosize

629 bytes sent via sql*Net to client

551 bytes received via sql*Net from client

2sql*Net roundtrips to/from client

0sorts (memory)

0sorts (disk)

1 rowsprocessed

走的是索引是INDEX FAST FULL SCAN 而非INDEX FULL SCAN(MIN/MAX)。

ORACLE无法用INDEX FULL SCAN(MIN/MAX)同时在最左边和最右边读取。

执行如下:

sql> select max,min from (select max(object_id) max from t)a,(select min(object_id) min from t) b;

Elapsed: 00:00:00.00

Execution Plan

----------------------------------------------------------

Plan hash value: 251798682

-----------------------------------------------------------------------------------------------

| Id| Operation | Name | Rows| Bytes | Cost (%cpu)| Time |

-----------------------------------------------------------------------------------------------

| 0| SELECT STATEMENT | |1 | 26 | 4 (0)|00:00:01 |

| 1| NESTED LOOPS | |1 | 26 | 4 (0)|00:00:01 |

| 2| VIEW | |1 | 13 | 2 (0)|00:00:01 |

| 3| SORT AGGREGATE | |1 | 5 | | |

| 4| INDEX FULL SCAN (MIN/MAX)|IDX1_OBJECT_ID | 1 | 5 |2 (0)| 00:00:01 |

| 5| VIEW | |1 | 13 | 2 (0)|00:00:01 |

| 6| SORT AGGREGATE | |1 | 5 | | |

| 7| INDEX FULL SCAN (MIN/MAX)|IDX1_OBJECT_ID | 1 | 5 |2 (0)| 00:00:01 |

-----------------------------------------------------------------------------------------------

Statistics

----------------------------------------------------------

1recursive calls

0 dbblock gets

4 consistent gets

0physical reads

0 redosize

607 bytes sent via sql*Net to client

551 bytes received via sql*Net from client

2sql*Net roundtrips to/from client

0sorts (memory)

0sorts (disk)

1 rowsprocessed

逻辑读总数是4. 所以,对于sql语句,需要足够的优化。

原文链接:https://www.f2er.com/oracle/207068.html

猜你在找的Oracle相关文章