Oracle 表的访问方式(1) ---全表扫描、通过ROWID访问表
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访问表的更多相关文章
- Oracle 表的访问方式(2)-----索引扫描
索引扫描(Index scan) 我们先通过index查找到数据对应的rowid值(对于非唯一索引可能返回多个rowid值),然后根据rowid直接从表中得到具体的数据,这种查找方式称为索引扫描或索引 ...
- oracle A用户访问B用户的表aa
在B中:grant select on aa to A; (还可以配置insert,update,delete权限)
- Oracle EM 的访问方式由HTTPS改为HTTP
打开命令提示符,依次运行以下命令: set ORACLE_HOSTNAME=%COMPUTERNAME% set ORACLE_UNQNAME=orcl rem 指向 dbhome_1\oc4j\j2 ...
- 表访问方式---->全表扫描(Full Table Scans, FTS)
全表扫描(Full Table Scans, FTS) 全表扫描是指Oracle在访问目标表里的数据时,会从该表所占用的第一个区(EXTENT)的第一个块(BLOCK)开始扫描,一直扫描到该表的高水位 ...
- 表访问方式---->通过ROWID访问表(table access by ROWID)
通过ROWID访问表(table access by ROWID) ROWID是一个伪列,即是一个非用户定义的列,而又实际存储于数据库之中.每一个表都有一个ROWID列,一个ROWID值 ...
- 全表 or 索引
这一篇文章证实了以前对MySQL优化程序的工作原理. MySQL就像一个人一样,总是聪明的去选择当前最快的方式去查询,而不是像Oracle数据那样死板地根据规格去查询. 查询的要求在于快.而对于数据库 ...
- 【ShardingSphere技术专题】「ShardingJDBC」SpringBoot之整合ShardingJDBC实现分库分表(JavaConfig方式)
前提介绍 ShardingSphere介绍 ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈,它由Sharding-JDBC.Sharding-Proxy和Shardin ...
- MYSQL的全表扫描,主键索引(聚集索引、第一索引),非主键索引(非聚集索引、第二索引),覆盖索引四种不同查询的分析
文章出处:http://inter12.iteye.com/blog/1430144 MYSQL的全表扫描,主键索引(聚集索引.第一索引),非主键索引(非聚集索引.第二索引),覆盖索引四种不同查询的分 ...
- MySQL中的全表扫描和索引树扫描
引言 在学习mysql时,我们经常会使用explain来查看sql查询的索引等优化手段的使用情况.在使用explain时,我们可以观察到,explain的输出有一个很关键的列,它就是type属性,ty ...
随机推荐
- PetaPoco使用要点
PetaPoco是一款适用于.Net 和Mono的微小.快速.单文件的微型ORM! 可以从这里获得PetaPoco: NuGet - http://nuget.org/List/Packages/Pe ...
- 【原创】C++链表如何像Python List一样支持多种数据类型
用过Python的码友都知道,Python中List支持多种数据类型,如下面代码所示链表li内的数据类型可以是整数,同时也可以是字符串,当然也可以是其他数据类型. 1: >>> li ...
- [Android]AndroidDesign中ActionBar探究1
概述 从Google IO 2013大会以来越来越多的Android应用开始遵循Android的设计风格,简单的就是google play和Gmail,在国内我们常用的软件像知乎.印象笔记,主要的界面 ...
- input输入框,回车激活按钮事件代码
<input type="text" name="输入框ID" id="输入框ID" onkeypress="if(even ...
- ionic项目的一些简单操作
1.首先保证开发环境没问题: 2.下载一个ionic项目:命令ionic start myApp tabs(myApp的项目的名称) 3.在运行项目之前,要先创建平台: ionic platform ...
- 剑指Offer34 数组中的逆序对
/************************************************************************* > File Name: 34_Invers ...
- c#中文件上传(1)
* * ;//3M picPath = Server.MapPath("........."); HttpFileCollection postfile = Context.Req ...
- Android高级音频应用
说到音频应用,首先想到的就是音乐播放器.有些播放器可以播放流媒体,有些可以播放本地音乐文件.随着Android平台的演变,需要更多高级的音频API.好在谷歌新增了这方面的API,支持低延迟的音频流媒体 ...
- Part 92 Significance of Thread Join and Thread IsAlive functions
Thread.Join & Thread.IsAlive functions Join blocks the current thread and makes it wait until th ...
- SQL server自定义函数实例
create function dbo.t_bh (@str varchar(20)) returns varchar(20) as begin declare @bh varchar(20),@le ...