网站首页 > 技术文章 正文
全扫描访问方法
Oracle必须将整个数据块读取到内存中以取得这个块中所存储的数据行的数据。所以当发生全扫描的时候,实际上优化器需要考虑两件事:必须读取多少个数据块以及每个数据块中有多少数据将被舍弃。
如何选择全扫描操作
全扫描不仅仅是与数据行有关,还与数据块以及丢弃有关。集合上面因素就可以得出全扫描是否有意义。即可能返回的数据行比例很小也有可能发生全表扫描。
下面示例:就算返回的数据行很小也发生全扫描操作
SQL> create table t1 as 2 select trunc((rownum/1)/100) id, 3 rpad(rownum,100) t_pad 4 from all_source 5 where rownum <= 10000; Table created. SQL> create table t2 as 2 select mod(rownum,100) id, 3 rpad(rownum,100) t_pad 4 from all_source 5 where rownum <=10000; Table created. SQL> select count(1) from t1; COUNT(1) ---------- 10000 SQL> select count(1) from t2; COUNT(1) ---------- 10000 SQL> create index t1_idx1 on t1(id); Index created. SQL> create index t2_idx1 on t2(id); Index created. SQL> exec dbms_stats.gather_table_stats(user,'T1',method_opt=>'FOR ALL COLUMNS SIZE 1' ,cascade=>TRUE); PL/SQL procedure successfully completed. SQL> exec dbms_stats.gather_table_stats(user,'T2',method_opt=>'FOR ALL COLUMNS SIZE 1' ,cascade=>TRUE); PL/SQL procedure successfully completed. SQL> set autotrace traceonly explain; SQL> select * from t1 where id=1; Execution Plan ---------------------------------------------------------- Plan hash value: 2623418078 --------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 99 | 10296 | 3 (0)| 00:00:01 | | 1 | TABLE ACCESS BY INDEX ROWID| T1 | 99 | 10296 | 3 (0)| 00:00:01 | |* 2 | INDEX RANGE SCAN | T1_IDX1 | 99 | | 1 (0)| 00:00:01 | --------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("ID"=1) SQL> select * from t2 where id=1; Execution Plan ---------------------------------------------------------- Plan hash value: 1513984157 -------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 100 | 10400 | 46 (0)| 00:00:01 | |* 1 | TABLE ACCESS FULL| T2 | 100 | 10400 | 46 (0)| 00:00:01 | -------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("ID"=1)
如上面的示例,两个表数据一样,返回的行数也一样,但是各自的扫表方式不一样。因为两张表的存储方式不同,导致扫描表数据的方式各异。基于存储方式的不同优化器的执行计划选择也可能不同。
全扫描与舍弃
全扫描是否高效的选择取决于需要访问的数据块的个数以及最终的结果集行数。
所访问的数据块数目以及舍弃的数量越大,全表扫描的成本越高。
随着时间的推移,新行被插入到表中使得表变得更大,舍弃这么多数据行的成本也不断增加,到一定程度优化器将会切换到使用索引扫描运算。
全扫描与多块读取
全扫描运算将会进行多块读取。即一个单独IO调用会请求多个块而不是一个。所请求的数据块数目是可变的,实际上可以是从一个到db_file_multiblock_read_count参数所指定的数目范围之间的任意个。
多块读取调用的限制如下:
1、oracle不得不读取超过一定边界范围的数据块,在这种情况下,oracle将会在一次调用中读取直到边界范围的数据块,然后发起另一次调用来读取剩余的块。
2、如果一个数据块已经在缓冲区缓存中,那么它将会作为多块读取的一部分重新读取一遍。oracle将会只读取那些尚在内存中的数据块,然后发起另一次读取调用来跳过这些数据块来读取剩下的,这意味着一个多块读取可能一次只读取一个块。假如,多块读取的计数是16个,需要读取的是编号为1-16的块,如果偶数编号的块已经在缓冲区缓存中了,那么在这个范围内的每一个奇数编号的块就需要进行一次单独的单块读取,在这个例子中,需要进行8次读取调用,每次读取一个该范围内的不在缓冲区缓存中的数据块。
3、超出了操作系统限制的多块读取大小,这取决于你的操作系统。因此是可变的。
另外可以提高db_filemutiblock_read_count参数值来提高全表扫描的效率。
全表扫描与高水位
关于全表扫描需要注意的最后一点是当对扫描进行多块读取调用时,oracle将最多读取到位于表中高水位线的数据块。高水位线标出了表中最后一块有数据写入的数据块。
猜你喜欢
- 2024-11-11 Oracle OAC数据分析系列:设置数值格式和货币符号
- 2024-11-11 Oracle 数据库之SQL分组函数 sql的分组函数
- 2024-11-11 Oracle数据立方体多维数据用CUBE处理
- 2024-11-11 MySQL的count()分析 mysql的count太慢优化
你 发表评论:
欢迎- 615℃几个Oracle空值处理函数 oracle处理null值的函数
- 608℃Oracle分析函数之Lag和Lead()使用
- 595℃0497-如何将Kerberos的CDH6.1从Oracle JDK 1.8迁移至OpenJDK 1.8
- 592℃Oracle数据库的单、多行函数 oracle执行多个sql语句
- 587℃Oracle 12c PDB迁移(一) oracle迁移到oceanbase
- 580℃【数据统计分析】详解Oracle分组函数之CUBE
- 569℃最佳实践 | 提效 47 倍,制造业生产 Oracle 迁移替换
- 560℃Oracle有哪些常见的函数? oracle中常用的函数
- 最近发表
-
- PageHelper - 最方便的 MyBatis 分页插件
- 面试二:pagehelper是怎么实现分页的,
- MyBatis如何实现分页查询?(mybatis-plus分页查询)
- SpringBoot 各种分页查询方式详解(全网最全)
- 如何在Linux上运行exe文件,怎么用linux运行windows软件
- 快速了解hive(快速了解美国50个州)
- Python 中的 pyodbc 库(pydbclib)
- Linux搭建Weblogic集群(linux weblogic部署项目步骤)
- 「DM专栏」DMDSC共享集群之部署(一)——共享存储配置
- 故障分析 | MySQL 派生表优化(mysql pipe)
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端路由 (61)
- 前端数组 (73)
- 前端js面试题 (50)
- 前端定时器 (59)
- 前端获取当前时间 (50)
- Oracle RAC (76)
- oracle恢复 (77)
- oracle 删除表 (52)
- oracle 用户名 (80)
- oracle 工具 (55)
- oracle 内存 (55)
- oracle 导出表 (62)
- oracle约束 (54)
- oracle 中文 (51)
- oracle链接 (54)
- oracle的函数 (58)
- 前端调试 (52)
本文暂时没有评论,来添加一个吧(●'◡'●)