今天通过v$sql_plan、v$sqlarea等视图,定位存在Table Access Full的脚本如下:
select d.id, d.caption from t_catalog d where parentid = 77 and isvalid = 1;
首先想得的就是这个条件字段上没索引,如是马上去检测,发现在parentid上有索引,对应的创建语句如下:
create index INDEX_T_CATALOG on t_catalog(parentid);
如是,查看查询数据与总数据量的比,发现为17比179,这个比率应该走索引才是,怀疑是索引问题,删除并创建复合索引:
drop index INDEX_T_CATALOG;
create index INDEX_T_CATALOG on t_catalog(parentid,isvalid);
可发现执行计划还是按Table Access Full方式查找数据:
SELECT STATEMENT, GOAL = ALL_ROWS 耗费=3 基数=18 字节=504 CPU 耗费=96077 IO 耗费=3 操作=SELECT STATEMENT
TABLE ACCESS FULL 对象所有者=MS 对象名称=T_CATALOG 耗费=3 基数=18 字节=504 CPU 耗费=96077 IO 耗费=3 对象实例=1 操作=TABLE ACCESS
TABLE ACCESS FULL 对象所有者=MS 对象名称=T_CATALOG 耗费=3 基数=18 字节=504 CPU 耗费=96077 IO 耗费=3 对象实例=1 操作=TABLE ACCESS
如是我就强制它走索引:
select /*+index(d,INDEX_T_CATALOG)*/ d.id, d.caption from t_catalog d where parentid = 77 and isvalid = 1
其对应的执行计划如下:
SELECT STATEMENT, GOAL = ALL_ROWS 耗费=6 基数=18 字节=504 CPU 耗费=52039 IO 耗费=6 操作=SELECT STATEMENT
TABLE ACCESS BY INDEX ROWID 对象所有者=MS 对象名称=T_CATALOG 耗费=6 基数=18 字节=504 CPU 耗费=52039 IO 耗费=6 对象实例=1 操作=TABLE ACCESS
INDEX RANGE SCAN 对象所有者=MS 对象名称=INDEX_MVS_D_CATALOG 耗费=1 基数=18 CPU 耗费=10921 IO 耗费=1 操作=INDEX
TABLE ACCESS BY INDEX ROWID 对象所有者=MS 对象名称=T_CATALOG 耗费=6 基数=18 字节=504 CPU 耗费=52039 IO 耗费=6 对象实例=1 操作=TABLE ACCESS
INDEX RANGE SCAN 对象所有者=MS 对象名称=INDEX_MVS_D_CATALOG 耗费=1 基数=18 CPU 耗费=10921 IO 耗费=1 操作=INDEX
可以看出,这样强制走索引的方式,效率更差,看来Oracle决定不走索引,还是有道理的。
到了这里,是不是对这个语句,就没有办法优化了咧,考虑到这个表数据平时维护得比较少,一般都是基于该表的查询,我觉得这种情况,就适合创建bitmap index了。
drop index INDEX_T_CATALOG;
create bitmap index INDEX_T_CATALOG on t_catalog(parentid,isvalid);
create bitmap index INDEX_T_CATALOG on t_catalog(parentid,isvalid);
去掉强制索引,再来看看这个bitmap index的效率,还是走的Table Access Full,加上强制索引,则执行计划如下:
SELECT STATEMENT, GOAL = ALL_ROWS 耗费=4 基数=18 字节=504 CPU 耗费=38047 IO 耗费=4 操作=SELECT STATEMENT
TABLE ACCESS BY INDEX ROWID 对象所有者=MVS 对象名称=MVS_D_CATALOG 耗费=4 基数=18 字节=504 CPU 耗费=38047 IO 耗费=4 对象实例=1 操作=TABLE ACCESS
BITMAP CONVERSION TO ROWIDS 操作=BITMAP CONVERSION
BITMAP INDEX SINGLE VALUE 对象所有者=MVS 对象名称=INDEX_MVS_D_CATALOG 操作=BITMAP INDEX
TABLE ACCESS BY INDEX ROWID 对象所有者=MVS 对象名称=MVS_D_CATALOG 耗费=4 基数=18 字节=504 CPU 耗费=38047 IO 耗费=4 对象实例=1 操作=TABLE ACCESS
BITMAP CONVERSION TO ROWIDS 操作=BITMAP CONVERSION
BITMAP INDEX SINGLE VALUE 对象所有者=MVS 对象名称=INDEX_MVS_D_CATALOG 操作=BITMAP INDEX
效率还是不如系统默认的全表扫描了,由此可见,及时加上了索引,系统采用不采用,也可查询条件的值有关系,不同的值,对应的执行计划可能完全不一样。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/9399028/viewspace-679461/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/9399028/viewspace-679461/