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. nodejs的mysql模块学习(十)连接池集群配置选项

    连接池集群选项 canRetry : 如果true ,连接池集群会在连接失败时尝试连接 默认true removeNodeErrorCount : 如果连接失败,节点的errCount增加.当erro ...

  2. .net对各表的操作详细到字段的更改记录的日志

    存入数据库中,目前的字段包括操作人,操作时间,sql语句,被修改的字段,字段原值,操作人的身份. /// <summary> /// 添加操作日志 /// </summary> ...

  3. 一个简单的Python爬虫

    写了一个抓taobao图片的爬虫,全是用if,for,while写的,比较简陋,入门作品. 从网页http://mm.taobao.com/json/request_top_list.htm?type ...

  4. Linux 内核模块可选信号

    一 . 内核模块可选信号 1 . 模块申明 (1). MODULE_LICENSE(遵守的协议) 申明该模块遵守的许可证协议,如:“GPL”."GPL V2" (2). MODUL ...

  5. MVC中的Routing

    Routing ASP.NET Routing模块的责任是将传入的浏览器请求映射为特有的MVC controller actions. public static void RegisterRoute ...

  6. thinkphp,javascript跨域请求解决方案

    javascript跨域请求解决方案 前言 对于很多前端或者做混合开发的同学,我们难免会遇到跨域发起请求业务,比如A站点向B站点请求数据等等.由于最近要做一个站点集群的项目,所以具体业务要求很多个站点 ...

  7. centos 6.5 安装lnmp(linux+nginx+mysql+php)

    参考:http://www.cnblogs.com/AloneSword/archive/2013/03/18/2966750.html (总结并简要) 一安装cmake wget -c http:/ ...

  8. MongoDB - The mongo Shell, Data Types in the mongo Shell

    MongoDB BSON provides support for additional data types than JSON. Drivers provide native support fo ...

  9. Python Opearte SQLAlchemy Do Something

    近段时间在看SQLAlchemy,总之万事开头难,但是么办法. Database Urls The create_engine() function produces an Engine object ...

  10. php返回json数据函数例子

    json_encode()函数用法. echo json_encode(array('a'=>'bbbb','c'=>'ddddd'); 这样就会生成一个标准的json格式的数据 代码如下 ...