1.Oracle访问表的方式

  全表扫描、通过ROWID访问表、索引扫描

2.全表扫描(Full Table Scans, FTS)

  为实现全表扫描,Oracle顺序地访问表中每条记录,并检查每一条记录是否满足WHERE语句的限制条件。ORACLE采用一次读入多个数据块(database block)的方式优化全表扫描,而不是只读取一个数据块,这极大的减少了I/O总次数,提高了系统的吞吐量,所以利用多块读的方法可以十分高效地实现全表扫描。需要注意的是只有在全表扫描的情况下才能使用多块读操作。在这种访问模式下,每个数据块只被读一次。

  使用FTS的前提条件:在较大的表上不建议使用全表扫描,除非取出数据的比较多,超过总量的5% -- 10%,或你想使用并行查询功能时。

全表扫描实例(TABLE ACCESS FULL)

 --创建表并插入数据,并进行查询。

 --创建数据库
SQL> create table t_captain
2 (
3 NO int,
4 NAME VARCHAR2(32),
5 WORKDAY DATE
6 )
7 / --创建序列
SQL> CREATE SEQUENCE SEQ_USERINFO_NO
2 INCREMENT BY 1 --每次加1
3 START WITH 1 --从1开始计数
4 / Sequence created. SQL> --插入100000条数据
begin
for i in 1..100000 loop
INSERT INTO T_CAPTAIN VALUES(SEQ_USERINFO_NO.nextval,'captain',SYSDATE);
end loop;
end;
/ commit; ----手动收集表的统计信息
SQL> exec dbms_stats.gather_table_stats('NC60','T_CAPTAIN'); PL/SQL procedure successfully completed. SQL> --查询NO=5000的结果
set autotrace traceonly --只看查询计划
select * from T_CAPTAIN where no = 5000; SQL> select * from T_CAPTAIN where no = 5000; Execution Plan
----------------------------------------------------------
Plan hash value: 3680104071 -------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 21 | 103 (1)| 00:00:02 |
|* 1 | TABLE ACCESS FULL| T_CAPTAIN | 1 | 21 | 103 (1)| 00:00:02 |
------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 1 - filter("NO"=5000) Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
376 consistent gets
0 physical reads
0 redo size
551 bytes sent via SQL*Net to client
419 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed SQL>

  从查询计划我们可以看到所采用的查询方式是“TABLE ACCESS FULL”。也正是因为采用全表扫描,所以consistent gets会大些

3.通过ROWID访问表(table access by ROWID)

  ROWID指出了该行所在的数据文件、数据块以及行在该块中的位置,所以通过ROWID来存取数据可以快速定位到目标数据上,是Oracle存取单行数据的最快方法。为了通过ROWID存取表,Oracle 首先要获取被选择行的ROWID,或者从语句的WHERE子句中得到,或者通过表的一个或多个索引的索引扫描得到。Oracle然后以得到的ROWID为依据定位每个被选择的行。下面给出使用rowid访问表的实例。

3.1.单个rowid的情形  

 --查看表上rowid
SQL> select rowid,no,name from T_CAPTAIN where no < 10; ROWID NO NAME
------------------ ---------- --------------------------------
AAAWOMAAGAAA//ZAAA 1 captain
AAAWOMAAGAAA//ZAAB 2 captain
AAAWOMAAGAAA//ZAAC 3 captain
AAAWOMAAGAAA//ZAAD 4 captain
AAAWOMAAGAAA//ZAAE 5 captain
AAAWOMAAGAAA//ZAAF 6 captain
AAAWOMAAGAAA//ZAAG 7 captain
AAAWOMAAGAAA//ZAAH 8 captain
AAAWOMAAGAAA//ZAAI 9 captain --根据rowid查询记录
SQL> set autotrace on
SQL> set line 200
SQL> select rowid,no,name from T_CAPTAIN where rowid='AAAWOMAAGAAA//ZAAA'; ROWID NO NAME
------------------ ---------- --------------------------------
AAAWOMAAGAAA//ZAAA 1 captain Execution Plan
----------------------------------------------------------
Plan hash value: 2487506745 ----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 21 | 1 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY USER ROWID| T_CAPTAIN | 1 | 21 | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------- Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
1 consistent gets
0 physical reads
0 redo size
558 bytes sent via SQL*Net to client
419 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed SQL>

  查询计划中说明该查询是的表访问方式是”TABLE ACCESS BY USER ROWID“,也就是直接通过USER ROWID来访问,这也是为什么只需要1次consistent gets的原因。

3.2.多个rowid的倾向

 SQL> select rowid,no,name from T_CAPTAIN where rowid in ('AAAWOMAAGAAA//ZAAG','AAAWOMAAGAAA//ZAAD','AAAWOMAAGAAA//ZAAI');

 ROWID                      NO NAME
------------------ ---------- --------------------------------
AAAWOMAAGAAA//ZAAD 4 captain
AAAWOMAAGAAA//ZAAG 7 captain Execution Plan
----------------------------------------------------------
Plan hash value: 2350621837 -----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 21 | 1 (0)| 00:00:01 |
| 1 | INLIST ITERATOR | | | | | |
| 2 | TABLE ACCESS BY USER ROWID| T_CAPTAIN | 1 | 21 | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------------- Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
2 consistent gets
0 physical reads
0 redo size
621 bytes sent via SQL*Net to client
419 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
2 rows processed SQL>

查询计划分析:

1.上面的执行计划中出现了INLIST ITERATOR,即INLIST迭代,该操作说明其子操作多次重复时,会出现该操作。

2.由于我们使用了in运算,且传递了2个rowid,故出现INLIST迭代操作

3.迭代操作意味着条件中的对象列表一个接一个的迭代传递给子操作

4.此时统计信息中的consistent gets为2,并不是因为传入的rowid有2个,假如传入的rowid有4个,consistent gets也等于2。

注意:使用ROWID进行查询的前提是我们明确知道了一个正确的ROWID,然后通过这个ROWID进行查询。所以这里所提到的所有ROWID 必须是真实存在的,否则会报错。

整理自网络

Oracle 表的访问方式(1) ---全表扫描、通过ROWID访问表的更多相关文章

  1. Oracle 表的访问方式(2)-----索引扫描

    索引扫描(Index scan) 我们先通过index查找到数据对应的rowid值(对于非唯一索引可能返回多个rowid值),然后根据rowid直接从表中得到具体的数据,这种查找方式称为索引扫描或索引 ...

  2. oracle A用户访问B用户的表aa

    在B中:grant select on aa to A; (还可以配置insert,update,delete权限)

  3. Oracle EM 的访问方式由HTTPS改为HTTP

    打开命令提示符,依次运行以下命令: set ORACLE_HOSTNAME=%COMPUTERNAME% set ORACLE_UNQNAME=orcl rem 指向 dbhome_1\oc4j\j2 ...

  4. 表访问方式---->全表扫描(Full Table Scans, FTS)

    全表扫描(Full Table Scans, FTS) 全表扫描是指Oracle在访问目标表里的数据时,会从该表所占用的第一个区(EXTENT)的第一个块(BLOCK)开始扫描,一直扫描到该表的高水位 ...

  5. 表访问方式---->通过ROWID访问表(table access by ROWID)

    通过ROWID访问表(table access by ROWID)        ROWID是一个伪列,即是一个非用户定义的列,而又实际存储于数据库之中.每一个表都有一个ROWID列,一个ROWID值 ...

  6. 全表 or 索引

    这一篇文章证实了以前对MySQL优化程序的工作原理. MySQL就像一个人一样,总是聪明的去选择当前最快的方式去查询,而不是像Oracle数据那样死板地根据规格去查询. 查询的要求在于快.而对于数据库 ...

  7. 【ShardingSphere技术专题】「ShardingJDBC」SpringBoot之整合ShardingJDBC实现分库分表(JavaConfig方式)

    前提介绍 ShardingSphere介绍 ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈,它由Sharding-JDBC.Sharding-Proxy和Shardin ...

  8. MYSQL的全表扫描,主键索引(聚集索引、第一索引),非主键索引(非聚集索引、第二索引),覆盖索引四种不同查询的分析

    文章出处:http://inter12.iteye.com/blog/1430144 MYSQL的全表扫描,主键索引(聚集索引.第一索引),非主键索引(非聚集索引.第二索引),覆盖索引四种不同查询的分 ...

  9. MySQL中的全表扫描和索引树扫描

    引言 在学习mysql时,我们经常会使用explain来查看sql查询的索引等优化手段的使用情况.在使用explain时,我们可以观察到,explain的输出有一个很关键的列,它就是type属性,ty ...

随机推荐

  1. 【阿里云产品公测】与云引擎ACE第一次亲密接触

    阿里云用户:林哥神话 公测当然是第一次了.这个第一次亲密接触,但话又说回来对ACE我一直都不是那感兴趣的,但是看到阿里介绍还是那般神奇,再加上200无代金券来更加给力.最后就申请了这次公测. 平时一直 ...

  2. 使用 mina 传输大字节数组

    转载自:http://seara520.blog.163.com/blog/static/16812769820103214817781/ 使用mina传输超过2k以上的数据时(采用tcp方式,如果是 ...

  3. javascript组件开发

    最近忙于重构项目,今天周末把在重构中的一些思想记记: 一.javascript的组件开发:基类的封装 由于这次重构项目需要对各种组件进行封装,并且这些组件的实现方式都差不多,所以想到对组件封装一个ba ...

  4. poj 3417 树形dp+LCA

    思路:我以前一直喜欢用根号n分段的LCA.在这题上挂了,第一次发现这样的LCA被卡.果断改用Tarjan离线算法求LCA. 当前节点为u,其子节点为v.那么: 当以v根的子树中含有连接子树以外点的边数 ...

  5. Laravel-Administrator enum使用数字key

    参考连接:Enum filter with numeric values 修改Fields\Enum::build()方法 $options['options'][] = array( 'id' =& ...

  6. angular-ui-router state.go not passing data to $stateParams

    app.js中定义了一个state如下,url接收一个id参数 $stateProvider.state("page.details", { url: "/details ...

  7. html5+css3第一屏滚屏动画效果

    详细内容请点击 在线预览立即下载 html5+css3第一屏滚屏动画效果. 转载自:http://tympanus.net/codrops/2014/05/22/inspiration-for-art ...

  8. SQLite&&SharedPreferences&&IO读写Sdcard学习笔记

    SQLite 轻量级的.嵌入式的.关系型数据库 Android.IOS等广泛使用的的数据库系统 SQLite数据库之中可以方便的使用SQL语句,实现数据的增加.修改.删除.查询等操作 SQLiteOp ...

  9. 北大ACM(POJ1014-Dividing)

    Question:http://poj.org/problem?id=1014 问题点:抽屉原理.dfs.多重背包. Memory: 248K Time: 16MS Language: C++ Res ...

  10. 利用 NUget包 EPPlus 实现数据导出到Excel(适用于DTcms)

    首先安装EPPlus 包