Oracle对单独使用max或min函数时给出了一种非常高效的访问路径,就是“INDEX FULL SCAN (MIN/MAX)”,该方法可以避免索引的全部读取,进一步提高数据结果的获取效率。
通过这个实验简单记录一下。
1.创建测试表
我们先创建一个包含一百万条记录的表t,在t表的第一个字段x上有主键。
sec@ora10g> select count(*) from t;
COUNT(*)
----------
1000000
2.开启autotrace功能查看一下max函数对应的执行计划
sec@ora10g> set autotrace on
sec@ora10g> select max(x) from t;
MAX(X)
----------
1000000
Elapsed: 00:00:00.00
Execution Plan
----------------------------------------------------------
Plan hash value: 1172912737
-----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 3 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 5 | | |
| 2 | INDEX FULL SCAN (MIN/MAX)| PK_T | 994K| 4858K| 3 (0)| 00:00:01 |
-----------------------------------------------------------------------------------
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
3 consistent gets
0 physical reads
0 redo size
513 bytes sent via SQL*Net to client
492 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
3.“INDEX FULL SCAN (MIN/MAX)”访问路径
此处SQL优化器不但可以识别到使用索引扫描可以提速,而且针对特定的max函数(或min函数)使用特有的“INDEX FULL SCAN (MIN/MAX)”访问路径来快速获取最大值(或最小值)。
使用这种访问路径获得最大值时,可以不必将所有的索引内容预读一遍,而是从索引尽量靠后的记录开始读,这样便可以更加快速地获得最大值。
4.如果max和min函数同时使用会有什么的执行计划呢?
sec@ora10g> select min(x), max(x) from t;
MIN(X) MAX(X)
---------- ----------
1 1000000
Elapsed: 00:00:00.21
Execution Plan
----------------------------------------------------------
Plan hash value: 949213647
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 466 (2)| 00:00:06 |
| 1 | SORT AGGREGATE | | 1 | 5 | | |
| 2 | INDEX FAST FULL SCAN| PK_T | 994K| 4858K| 466 (2)| 00:00:06 |
------------------------------------------------------------------------------
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
2102 consistent gets
0 physical reads
0 redo size
580 bytes sent via SQL*Net to client
492 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
通过上面的执行计划可见,min(x)和max(x)函数同时使用时是无法使用“INDEX FULL SCAN (MIN/MAX)”的。原因很简单,同一张表既想得到最小值又想得到最大值只能将所有的数据预读一遍才知道。此时SQL优化器给出的方法是“INDEX FAST FULL SCAN”。也就是说仅用索引本身就可以回答这个问题,无需访问表t,这也是一种高效获得数据的方法,类似于将原来的大表重新构造了一个以索引形式存在的“小表”。
5.小结
Oracle在常用查询上给出的执行计划有助于高效的完成任务。
Oracle细节之处很精彩。
secooler
09.11.26
-- The End --
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70034820/viewspace-2994018/
,如需转载,请注明出处,否则将追究法律责任。