数据库扫描方式解析

1) 全表扫描(Full Table Scans, FTS)
为实现全表扫描,Oracle读取表中全部的行,并检查每一行是否知足语句的WHERE限制条件。Oracle顺序地读取分配给表的每一个数据块,直到读到表的最高水线处(high water mark, HWM,标识表的最后一个数据块)。一个多块读操做可使一次I/O能读取多块数据块(db_block_multiblock_read_count参数设定),而不是只读取一个数据块,这极大的减小了I/O总次数,提升了系统的吞吐量,因此利用多块读的方法能够十分高效地实现全表扫描, 并且只有在全表扫描的状况下才能使用多块读操做。在这种访问模式下,每一个数据块只被读一次。因为HWM标识最后一块被读入的数据,而delete操做不影响HWM值,因此一个表的全部数据被delete后,其全表扫描的时间不会有改善,通常咱们须要使用truncate命令来使HWM值归为0。幸运的是oracle 10G后,能够人工收缩HWM的值。
由FTS模式读入的数据被放到高速缓存的Least Recently Used (LRU)列表的尾部,这样可使其快速交换出内存,从而不使内存重要的数据被交换出内存。
使用FTS的前提条件:在较大的表上不建议使用全表扫描,除非取出数据的比较多,超过总量的5% -- 10%,或你想使用并行查询功能时。
使用全表扫描的例子:
~~~~~~~~~~~~~~~~~~~~~~~~
SQL> explain plan for select * from dual;
Query Plan
-----------------------------------------
SELECT STATEMENT [CHOOSE] Cost=
TABLE ACCESS FULL DUAL
2) 经过ROWID的表存取(Table Access by ROWID或rowid lookup)
行的ROWID指出了该行所在的数据文件、数据块以及行在该块中的位置,因此经过ROWID来存取数据能够快速定位到目标数据上,是Oracle存取单行数据的最快方法。
为了经过ROWID存取表,Oracle 首先要获取被选择行的ROWID,或者从语句的WHERE子句中获得,或者经过表的一个或多个索引的索引扫描获得。Oracle而后以获得的ROWID为依据定位每一个被选择的行。
这种存取方法不会用到多块读操做,一次I/O只能读取一个数据块。咱们会常常在执行计划中看到该存取方法,如经过索引查询数据。
使用ROWID存取的方法:
SQL> explain plan for select * from dept where rowid = 'AAAAyGAADAAAAATAAF';
Query Plan
------------------------------------
SELECT STATEMENT [CHOOSE] Cost=1
TABLE ACCESS BY ROWID DEPT [ANALYZED]
3)索引扫描(Index Scan或index lookup)
咱们先经过index查找到数据对应的rowid值(对于非惟一索引可能返回多个rowid值),而后根据rowid直接从表中获得具体的数据,这种查找方式称为索引扫描或索引查找(index lookup)。一个rowid惟一的表示一行数据,该行对应的数据块是经过一次i/o获得的,在此状况下该次i/o只会读取一个数据库块。 23
在索引中,除了存储每一个索引的值外,索引还存储具备此值的行对应的ROWID值。索引扫描能够由2步组成:(1) 扫描索引获得对应的rowid值。 (2) 经过找到的rowid从表中读出具体的数据。 每步都是单独的一次I/O,可是对于索引,因为常常使用,绝大多数都已经CACHE到内存中,因此第1步的I/O常常是逻辑I/O,即数据能够从内存中获得。可是对于第2步来讲,若是表比较大,则其数据不可能全在内存中,因此其I/O颇有多是物理I/O,这是一个机械操做,相对逻辑I/O来讲,是极其费时间的。因此若是多大表进行索引扫描,取出的数据若是大于总量的5% -- 10%,使用索引扫描会效率降低不少。 以下列所示: SQL> explain plan for select empno, ename from emp where empno=10; Query Plan ------------------------------------ SELECT STATEMENT [CHOOSE] Cost=1 TABLE ACCESS BY ROWID EMP [ANALYZED] INDEX UNIQUE SCAN EMP_I1 注意TABLE ACCESS BY ROWID EMP部分,这代表这不是经过FTS存取路径访问数据,而是经过rowid lookup存取路径访问数据的。在此例中,所须要的rowid是因为在索引查找empno列的值获得的,这种方式是INDEX UNIQUE SCAN查找,后面给予介绍,EMP_I1为使用的进行索引查找的索引名字。
相关文章
相关标签/搜索