局部范围扫描的条件
通常在SQL中使用了ORDER BY 将无法实现局部范围扫描,但如果优化器选择的驱动索引列与ORDER BY 排序列相同,则可以按照局部范围扫描的方式进行处理。由此可见,并不是所有使用了ORDER BY的SQL都无法实现局部范围扫描,唯独在执行计划中出现了SORT时才真正地无法实现局部范围扫描。
满足驱动查询条件的数据范围越小,所执行的操作量就越少;而满足过滤查询条件的数据范围越大,所执行的操作量越少。
1.满足驱动查询条件的数据范围越小越有效。在此情况下,由于其他查询条件对执行速度的影响比较小,所以始终可以确保较快的执行速度。
2.在满足驱动查询条件和其他查询条件的数据范围都大的情况下,始终可以确保具有较快的执行速度。然后,满足其他查询条件的数据范围较小时,反倒容易影响执行速度。
3.在满足驱动查询条件的数据范围较大,而满足其他查询条件的数据范围较小,从而导致执行速度缓慢的情况下,如果把数据范围较小的查询条件作为驱动查询条件来使用,则可以提高执行速度。
满足驱动查询条件的数据范围 | 满足过滤查询条件的数据范围 | 执行速度 | 采取的措施 |
小 | 小 | 快 |
|
大 | 快 |
| |
大 | 小 | 慢 | 交换驱动查询条件与过滤条件的角色 |
大 | 快 |
|
向局部范围扫描引导的方法
1.利用访问路径实现对Sort的代替
索引列序也是能否实现局部范围扫描的一个非常重要的前提条件。在要求按照WHERE中没有使用到的列进行排序的情况下,为了实现在SQL中不使用ORDER BY 排序,把该列添加到索引中是一个非常好的解决方案。
例:
SELECT ord_dept,ordqty*1000
FROM order
WHERE ord_date like ‘2011%’ ORDER BY ord_dept desc;
在该SQL中,负责数据读取的列是“ORD_DATE”,而在ORDER BY 中所使用的列却是“ORD_DEPT DESC”。如果满足驱动查询条件“ord_date like ‘2011%’”的数据范围很大,则无法获得较好的执行速度。因此,需要对SQL做适当的变形:
SELECT /*+ INDEX_DESC(a ord_dept_index) */
Ord_dept,ordqty*1000
FROM order a
WHERE ord_date like ‘2011%’ AND ord_dept>’’
当两个条件的查询数据范围大时:“满足驱动查询条件的数据范围大,且满足其他查询条件的数据范围也大时,执行速度快”。
通过采取一些措施将原有的驱动查询条件变为过滤查询条件,原来的过滤查询条件变为驱动查询条件,从而实现了局部范围扫描。
2.只使用索引的局部范围扫描
为了有效处理大范围数据而不断努力的原因,并不是因为扫描的索引中数据范围比较大,而是当所要处理的数据范围比较大时,经过索引对表的随机读取会大大增加。索引只在查找第一个满足条件的索引行时发生随机读取,之后执行的是连续扫描,但是从表中读取数据始终都是按照随机方式进行的。
通过使用各种方法将亲密度较高的列筛选出来,分析其使用频度、读取条件中的比较运算符、分布度等内容来决定列序。
3.灵活使用MIN、MAX局部范围扫描
4.FILTER型局部范围扫描
EXISTS是检查子查询中的结果是否存在的布尔型函数,如果存在就返回TRUE,否则返回FALSE。
5.利用ROWNUM的局部范围扫描
6.利用嵌套视图的局部范围扫描
将必须使用全部范围扫描的部分捆绑在嵌套视图中,以确保视图之外的部分能够以局部范围扫描的方式来执行。
7.利用函数的局部范围扫描
8.利用查询语句二元化特性的局部范围扫描