Oracle对单独使用max或min函数时给出了一种非常高效的访问路径,就是“INDEX FULL SCAN (MIN/MAX)”,该方法可以避免索引的全部读取,进一步提高数据结果的获取效率。
通过这个实验简单记录一下。
1.创建测试表
create table T ( x INTEGER, y INTEGER, z INTEGER );
我们先创建一个包含百万条记录的表t,在t表的第一个字段x上有主键(或者唯一索引)
创建唯一索引
create unique index CUX.CUX_INDEX_UNIOX01 on T (X);
批量插入100W条记录
select rownum, to_char(rownum+10),to_char(rownum+10)from dual connect by level <= 1000000;
查询:
select count(*) from t;
2.查看一下max函数对应的执行计划
3.“INDEX FULL SCAN (MIN/MAX)”访问路径
此处SQL优化器不但可以识别到使用索引扫描可以提速,而且针对特定的max函数(或min函数)使用特有的“INDEX FULL SCAN (MIN/MAX)”访问路径来快速获取最大值(或最小值)。
使用这种访问路径获得最大值时,可以不必将所有的索引内容预读一遍,而是从索引尽量靠后的记录开始读,这样便可以更加快速地获得最大值。
4.如果max和min函数同时使用会有什么的执行计划呢?
select min(x), max(x) from t;
5、采用全表连接可以优化查询时间
select max(t.x) from t union all select min(xt.x) from t xt)
通过上面的执行计划可见,min(x)和max(x)函数同时使用时是无法使用“INDEX FULL SCAN (MIN/MAX)”的。原因很简单,同一张表既想得到最小值又想得到最大值只能将所有的数据预读一遍才知道。此时SQL优化器给出的方法是“INDEX FAST FULL SCAN”。也就是说仅用索引本身就可以回答这个问题,无需访问表t,这也是一种高效获得数据的方法,类似于将原来的大表重新构造了一个以索引形式存在的“小表”。