`

详述逻辑读

阅读更多

这篇实验讨论下数据的读写过程.
    我们都知道,数据块是oracle最基本的读写单位,但用户所需要的数据,并不是整个块,而是块中的行,或列.当用户发出SQL语句时,此语句被解析执行完毕,就开始了数据的抓取阶段,在此阶段,服务器进程会先将行所在的数据块从数据文件中读入buffer cache,这个过程叫做物理读.物理读,每读取一个块,就算一次物理读.当块被送进buffer cache后,并不能立即将块传给用户,因为用户所需要的并不整个块,而是块中的行.从buffer cache的块中读取行的过程,就是逻辑读.为了完成一次逻辑读,服务器进程先要在hash表中查找块所在的cache buffer 链.找到之后,需要在这个链上加一个cache buffer chains 闩,加闩成功之后,就在这个链中寻找指定的块,并在块上加一个pin锁.并释放cache buffer chains闩.然后就可以访问块中的行了.服务器进程不会将块中所有满足条件的行一次取出,而是根据你的抓取命令,每次取一定数量的行.这些行取出之后,会经由PGA传给客户端用户.行一旦从buffer cache中取出,会话要释放掉在块上所加的PIN.本次逻辑读就算结束.如果还要再抓取块中剩余的行,服务器进程要再次申请获得cache bufffer链闩.再次在块上加PIN.这就算是另外一次逻辑读咯.也就是说,服务器进程每申请一次cache buffer链闩,就是一次逻辑读.而每次逻辑读所读取的行的数量,可以在抓取命令中进行设置.
    逻辑读和Cache buffer chains闩关系密切,TOM曾有文章提到,进程每申请一次Cache buffer chains闩,就是一次逻辑读。但是,逻辑读并不等同于Cache buffer chains闩,每次逻辑读,在9i中至少需要获得两Cache buffer chains闩。逻辑读是指在Hash表中定位块的这个过程。

下面是我的测试:
步1:建立测试表:
create table jj_one(id number(5),name char(40));

步2:插入100行
begin
   for i in 1..100 loop
     insert into jj_one values(i,'aaa');
   end loop;
end;
/

或:insert into jj_one select rownum,'aaa' from dba_objects where rownum<=100;

步3:显示一下表中行的分布
sid=10 pid=11> select bk,max(id),min(id) from (select dbms_rowid.rowid_block_number(rowid) bk,id from jj_one) group by bk;

        BK    MAX(ID)    MIN(ID)
---------- ---------- ----------
     42594         81          1
     42595        100         82

可以看到,表共占两个块,ID从1到81的行在块42594中,ID从82到100的行在42595中。

步4:设备批量读取参数为15
sid=10 pid=11> set arraysize 15
因为9i或10g中的默认值都是15,如果并没有更改过这个设置,此步也可省去。

步5:查看1行:
sid=11 pid=12> set autot trace stat
sid=11 pid=12> select * from jj_one where id<=1;


统计信息
----------------------------------------------------------
          0  recursive calls
          6  consistent gets
          0  physical reads
        458  bytes sent via SQL*Net to client
        372  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  rows processed
(省略无关行)

逻辑读为6

步6:查询15行以内:
sid=11 pid=12> select * from jj_one where id<=2;

统计信息
----------------------------------------------------------
          0  recursive calls
          6  consistent gets
          0  physical reads
        493  bytes sent via SQL*Net to client
        372  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          2  rows processed

在抓取行数小于15的情况下,逻辑读始终为6。

步7:查询16行以上:
sid=11 pid=12> select * from jj_one where id<=16;

已选择16行。

统计信息
----------------------------------------------------------
          0  recursive calls
          7  consistent gets
          0  physical reads
        699  bytes sent via SQL*Net to client
        383  bytes received via SQL*Net from client
          3  SQL*Net roundtrips to/from client
         16  rows processed

逻辑读已经变成7次。

注意,在10G中,对块读的算法有改进。以同样的谓词条件,访问同样的行时,第一次访问时的逻辑读要比以后再行访问时多的多。因此,在10G中,同样的命令,多执行几次,这样看到的结果比较全面。

还有一点,访问15行以内时,为什么会有6次逻辑读?不应该是1次吗?这里,我相信Set autot trace stat命令本身有一定的原因,如果用下面的静态游标:

sid=10 pid=11> alter session set events '10046 trace name context forever ,level 14';
会话已更改。

declare
  type mid is table of jj_one.id%type;
  mid1 mid;
  cursor c is select id from jj_one where id>=1 and id<=15;
begin
  open c;
  fetch c bulk collect into mid1 limit 15;
  dbms_output.put_line(c%rowcount);
  close c;
end;
/

sid=10 pid=11> alter session set events '10046 trace name context off';
会话已更改。

用Tkprof格式化跟踪结果:
E:\oracle\admin\mytwo\udump>tkprof mytwo_ora_756.trc m3.txt

查看M3.txt文件:
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        1      0.00       0.00          0          3          0          15
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        3      0.00       0.00          0          3          0          15

逻辑读只有3次。这3次逻辑读,有一次是针对行所在块的,其余两次是针对段头的。


实验完毕

从上面的实验中可以看出,“成批读取”中,批大小的设定,可以影响逻辑读的数量。批大小越大,读相同数量的行,逻辑读就越少。而且服务端和客户端交互的次数也越少,由网络传输的数据也可以减少,下面看一下测试:
批大小为1:
sid=11 pid=12> set arraysize 1
sid=11 pid=12> select * from jj_one;
已选择100行。
统计信息
----------------------------------------------------------
         54  consistent gets
       7206  bytes sent via SQL*Net to client
        911  bytes received via SQL*Net from client
         51  SQL*Net roundtrips to/from client
        100  rows processed
批大小为100:
sid=11 pid=12> set arraysize 100
sid=11 pid=12> select * from jj_one;
已选择100行。
统计信息
----------------------------------------------------------
          6  consistent gets
       1277  bytes sent via SQL*Net to client
        372  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
        100  rows processed

差别是很明显的,bytes sent via SQL*Net to client的数值,相差了6倍左右。

但这并不代表将批大小设置的越高,速度就越快,否则,Oracle直接将它设置为一个最大的值,不就行了,干吗还要让我们去自己调节呢!
行从Buffer cache中读出来后,会先缓存在PGA中(具体是在游标的运行时区),然后再传给客户端。如果批大小过大,在PGA、客户端占用的内存也会增大。而且,如果渐歇性的在网络上传输大量数据,对网络也会有一定影响。下面来观察一下批大小对PGA的影响:
在会话11中执行如下过程:
declare
  type mid is table of t1.id%type;
  mid1 mid;
  cursor c is select id from t1;
begin
  open c;
  loop
    fetch c bulk collect into mid1 limit 5000;
  exit when c%notfound;
  end loop;
  dbms_output.put_line(c%rowcount);
  close c;
end;
/

在另一会话中观察会话11的内存占用情况:
sid=10 pid=11> @pga   --此脚本下面有说明
输入 user 的值:  11
原值    7: and b.sid= &user
新值    7: and b.sid= 11

  PGA Used  PGA Alloc    PGA Max
---------- ---------- ----------
    561508     779492     779492


然后将会话11中过程的批大小改为1:fetch c bulk collect into mid1 limit 5000; 再试一次

在另一会话观察会话11的PGA占用情况:
sid=10 pid=11> @pga
输入 user 的值:  11
原值    7: and b.sid= &user
新值    7: and b.sid= 11

  PGA Used  PGA Alloc    PGA Max
---------- ---------- ----------
    184388     250668     250668

批大小为5000时的内存占用,是批大小为1时的3倍左右。另外,测试表一定要大一些,我的测试表是1000000行,否则不容易看到结果。在10G中,可以得到基本相同的结果。

PGA.SQL脚本如下:
--pga_by_process.sql:
SELECT
a.pga_used_mem "PGA Used",
a.pga_alloc_mem "PGA Alloc",
a.pga_max_mem "PGA Max" 
FROM v$process a,v$session b
where a.addr = b.paddr
and b.sid= &user 
/

分享到:
评论

相关推荐

    0718、具有脉冲指示的逻辑探头.zip

    后者文件名可能是主文档,可能是一份详细的报告、教程或用户手册,详述了具有脉冲指示的逻辑探头的工作原理、操作方法、功能特性,以及如何在实际应用中有效地使用它。 逻辑探头的关键知识点可能包括: 1. **基本...

    北邮数字逻辑课程设计频率计

    6. **显示模块**:将计算结果转化为人类可读的形式,可能是数码管显示或者通过串行通信接口传送到计算机进行显示。 7. **控制逻辑**:设计必要的控制逻辑,如启动/停止测量、清零计数器等功能。 8. **电路实现与调试...

    并发问题详述(sql)

    - **事务**:事务是一系列数据库操作的逻辑单元,具有ACID属性(原子性、一致性、隔离性、持久性)。原子性保证事务中的所有操作要么全部成功,要么全部失败;一致性确保事务结束后,数据库保持有效状态;隔离性防止...

    如何写读书心得体会.doc

    引言简单介绍所读书籍或文章,主体部分详述理解和感悟,结论部分则概括主要收获,或者提出未来的行动计划。 读书是提升自我、拓宽视野的重要途径,写好读书心得体会能帮助我们更好地消化吸收所学,也能激发他人阅读...

    多媒体课室监控管理系统详述.doc

    【多媒体课室监控管理系统详述】 多媒体课室监控管理系统是一种集成化的解决方案,旨在提升教育环境的管理和安全性。系统采用先进的技术和设备,如S3C2410微处理器、嵌入式Linux操作系统、Zigbee无线传感器网络以及...

    小学生怎样写好读后感.doc

    主体部分通过叙述与议论相结合的方式,详述阅读过程中的感受,展示思想的形成过程;结尾部分则将感受与现实生活相联系,探讨如何将所学应用于实践,提出改进的建议。 在写作时,要注意避免过多地复述原文,而是应该...

    linux与unix shell编程指南读书笔记.rar

    3. 逻辑运算符:`&&`表示逻辑与,`||`表示逻辑或,用于连接条件。 四、数组和关联数组 在Bash 4.0及更高版本中,支持数组和关联数组,允许存储多个值。如`myarray=("apple" "banana" "cherry")`。 五、Shell脚本...

    怎么写英文读书报告共7篇.doc

    3. **保持原有的逻辑顺序**:遵循原文的结构和思路,不要随意调整观点的排列。 4. **独立性**:总结应自成一体,能独立传达原文的主要思想,读者无需参考原文就能理解。 随着学生学术水平的提高,读书报告的内容会...

    电信设备-遥控器搜寻方法、移动终端及计算机可读存储介质.zip

    总的来说,这个压缩包可能包含一份详细的技术文档或专利申请,详述了如何在移动终端上实现遥控器的搜寻功能,并利用特定的计算机可读存储介质进行数据存储和传输。这些技术对于提升用户体验,优化家庭自动化系统,...

    小游戏源码-读心小博士.rar

    【知识点详述】 1. **游戏开发基础**:源码可以让我们了解游戏开发的基本架构,包括游戏循环、事件处理、对象和场景管理等。 2. **编程语言应用**:根据源码使用的语言,我们可以深入学习该语言的特性和最佳实践,...

    毕设&课程作业_挑战杯项目-AI智能点读系统平台App(小程序).zip

    源代码是实现系统功能的关键部分,包括前端UI界面和后端逻辑处理;测试报告则记录了测试过程和结果,以验证系统的功能正确性和性能指标。 总的来说,这个项目展示了学生如何将理论知识应用于实践,开发出一个结合...

    读秀包库全文下载器自己写的小程序.zip

    2. **数据库检索原理**:读秀包库的资源存储在数据库中,下载器可能需要理解这些资源的数据库查询逻辑,包括关键词搜索、分类筛选等,以精确定位目标文件。 3. **文件处理和解析**:获取到的资源通常以HTML、PDF或...

    悦读打卡需求分析报告1

    【需求分析】报告的核心是明确并详述"悦读打卡"小程序的功能和目标,以便于开发者、测试者和用户理解其工作原理和预期效果。该报告涵盖了以下几个关键方面: 1. **项目背景**:悦读打卡小程序由"集合啦!软工小队...

    RocksDB调优指南.docx

    读放大衡量的是执行一次查询所需的数据读取次数,包括逻辑读和物理读。逻辑读虽然更便宜,但会增加CPU负担。空间放大则是数据库文件占用的磁盘空间与实际数据大小的比例,控制空间放大有助于避免磁盘空间耗尽。 ...

    FPGA与SRAM相结合完成大容量数据存储

    文章还提到使用VHDL程序来实现上述的控制逻辑,但具体的VHDL代码未被提供完整,无法详述其编程细节。然而,可以推断VHDL代码会涉及到计数器、状态机和同步逻辑的设计,以确保FPGA和SRAM之间正确且高效的数据传输。 ...

    电信设备-配置系统审计服务的方法、信息处理装置及可读存储介质.zip

    2. **配置方法**:文件可能详述了如何在电信设备上设置和定制审计服务。这通常包括设定审计策略、定义要记录的事件类型、配置审计日志的存储位置和管理,以及如何开启或关闭特定的审计功能。 3. **信息处理装置**:...

    采用S7-300PLC改造英格索兰空压机控制系统.pdf

    知识点详述: 1. 空压机组控制系统老化问题: - 英格索兰空压机组的电气操作显示屏内部液晶显示面板严重老化,影响正常读数。 - 控制操作的24V电源辅助配套设备使用寿命已到,主控单板机上的电子器件老化,导致...

    数字电子技术基础第五版期末考试题收集.pdf

    20. 随机存取存储器(RAM):具有读/写功能,选项a正确。 填空题的答案因题目未给出,这里不详述。逻辑函数的化简和电路分析设计同样需要具体题目内容才能进行详细解答。 这些知识点涵盖了数字电子技术的基础内容...

    策略产品经理基础知识:2.3策略需求文档.docx

    需求详述部分主要讲述解决方案的实现细节,包括触发条件、考虑因素、呈现结果、问题背景、计算逻辑等信息。这个部分的目的是为了帮助产品经理和开发团队更好地理解解决方案的实现细节。 5. 统计和监控需求 统计和...

    智能卡的生命周期第1阶段详述

    设计阶段涉及到电路布局、逻辑优化和功耗管理。制版使用光刻技术在硅片上形成复杂的电路结构。晶圆制造通过扩散、沉积和蚀刻等步骤实现。封装则是将处理后的晶圆切割成单个芯片,并安装在卡片基板上。最后,每个微...

Global site tag (gtag.js) - Google Analytics