简答题 6.  表的访问方式有哪几种?
【正确答案】访问表的方式也称为优化器访问路径,主要有3种访问路径:全表扫描(FULL TABLE SCAN,FTS)、索引扫描(INDEX SCAN)和ROWID扫描。
   (1)全表扫描(FULL TABLE SCAN,FTS)  全表扫描将读取高水位(High Warter Mark,HWM)之下的所有数据块,所有行都要经WHERE子句过滤来判断是否满足条件。当Oracle执行全表扫描时,会按顺序读取每个块且只读一次,如果能够一次读取多个块,那么可以有效地提高效率,初始化参数DB_FILE_MULTIBLOCK_READ_COUNT用来设置在一次I/O中可以读取多少个数据块。通常应该避免全表扫描,但是在检索大量数据时全表扫描优于索引扫描,这正是因为全表扫描可以在一次I/O中读取多个块,从而减少了I/O的次数。在使用全表扫描的同时也可以使用并行来提高扫描的速度。全表扫描的Hint为:FULL(T)。
   CBO优化器在以下几种情况下会选择全表扫描:
   1)无合适的索引。
   2)检索表中绝大多数的数据。
   3)表非常小。例如,表中的块小于DB_FILE_MULTIBLOCK_READ_COUNT,只需一次I/O。如果这样的表被频繁使用,应该执行“ALTER TABLE TABLE_NAME STORAGE(BUFFER_POOL KEEP);”将表保存在内存中。
   4)高并行度。如果在表级设置了较高的并行度,例如“ALTER TABLE T_NAME PARALLEL 4;”,那么通常会选择全表扫描。通常建议在语句级用HINT来实现并行,例如/*+FULL(T_NAME)PARALLEL(T-NAME 4)*/。
   5)太旧的统计数据。如果表没有进行过分析或很久没有再次分析,那么CBO可能会错误地认为表含有极少的数据块。
   6)在语句中嵌入了全表扫描的Hint。
   7)WHERE子句的索引列上只存在极少数不同的值。
   需要注意的是,由于全表扫描是扫描高水位以下的所有数据块,所以即使使用DELETE语句清空了目标表中的所有数据,高水位线还是会在原来的位置,这意味着对该表的全表扫描操作所耗费的时间与删除之前相比并不会有明显的改观。
   (2)索引扫描(INDEX SCAN)  索引不仅包含被索引的字段值,还包含行的位置标识ROWID,如果SQL语句只检索索引字段,那么Oracle将直接从索引中读取而不需要通过ROWID去访问表;如果SQL语句通过索引检索其他字段值,那么Oracle通过索引获得ROWD再回表读就可以迅速找到需要的内容。
   索引扫描类型见表。
   
【答案解析】