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 ...
随机推荐
- Boost.Foreach
BOOST_FOREACH简化了C++的循环遍历序列元素. 支持的序列类型:Boost.Range识别的序列 STL容器 数组 Null-terminated String std::pair of ...
- 9. Android框架和工具之 SlidingMenu(抽屉菜单)
详见为知笔记:Android / Android用户界面优化 / Android SlidingMenu菜单栏程序设计
- 【开源项目5】测滑菜单MenuDrawer的使用以及解析
在安卓中左右侧滑菜单的使用用的比ios多得多,可能是谷歌带的头吧,几乎所有的谷歌应用都有侧滑菜单.谷歌没有开放这个源码,在一个成熟的开源代码出现之前,大家都是各自为战,偶尔能看到一个勉强实现了的.Me ...
- 【转】Eclipse中一键调用javah生成jni的头文件
这里定义了一个本地方法jni_test,该方法返回一个String.其中System.loadLibrary是用来加载本地库的(dll或者so). 有了这个类以后,就可以调用javac命令编译,得到E ...
- Java Script基础(十一) 表单验证
一.表单验证的必要性: 表单验证在客户端和服务器端,客户端验证实际是直接调用JavaScript脚本对用户输入的数据进行验证:而服务器也同样可以实现数据验证,但是当服务器压力过大时,资源损耗会比较严重 ...
- jQuery:节点(插入,复制,替换,删除)操作
<html> <head> <meta http-equiv="Content-Type" content="text/html; char ...
- [转]在WPF中使用WinForm控件方法
本文转自:http://blog.csdn.net/lianchangshuai/article/details/6415241 下面以在Wpf中添加ZedGraph(用于创建任意数据的二维线型.条型 ...
- 启动 Eclipse 弹出“Failed to load the JNI shared library jvm.dll”错误的解决方法!&&在eclipse.ini中为eclipse指定jdk启动
参考:http://blog.csdn.net/zyz511919766/article/details/7442633 http://blog.sina.com.cn/s/blog_028f0c1c ...
- MVC 菜鸟学习记录2
自定义Html.Helper扩展方法 在Models文件夹下新建一个静态类,取名为:MyHtmlHelper.cs 将MyHtmlHelper设置为static,并写入以下的一个静态方法 public ...
- 阿里巴巴的分布式应用框架-dubbo负载均衡策略--- 一致哈希算法
dubbo是阿里巴巴公司开发的一个开源分布式应用框架,基于服务的发布者和订阅者,服务者启动服务向注册中心发布自己的服务:消费者(订阅者)启动服务器向注册中心订阅所需要的服务.注册中心将订阅的服务注册列 ...