0

0

Oracle读取事件的命名理由

php中文网

php中文网

发布时间:2016-06-07 15:45:53

|

1233人浏览过

|

来源于php中文网

原创

db file sequential read与db file scattered read这两个等待事件在今天又让我们重温了一下2年前的一次争论, 大家对于这两个事件以及其名称的理解进行了多个角度的解读, 我觉得我有责任将Jeff Holt在多年前的这篇旧文翻译出来, 以助后来者理解这两个让人迷惑

db file sequential read与db file scattered read这两个等待事件在今天又让我们重温了一下2年前的一次争论, 大家对于这两个事件以及其名称的理解进行了多个角度的解读, 我觉得我有责任将Jeff Holt在多年前的这篇旧文翻译出来, 以助后来者理解这两个让人迷惑的概念. 翻译的比较仓促, 不足之处尽情谅解 Why are Oracle’s Read Events Named Backwards? 原文版权归Jeff Holt以及Hotsos公司所有.

为什么Oracle的读取事件使用”向后兼容的命名方式”?
By Jeff Holt Translated by Jametong

在几乎所有的oracle跟踪文件中,都有两个出现频繁的事件:db file sequential readdb file scattered read.这些事件表明oracle内核请求从磁盘读取数据块.

当我们想到磁盘时,我们熟悉的顺序访问(sequential read)的概念是,一个进程从磁盘读取大块的连续数据.当Oracle执行一次全表扫描时,会在一次大I/O中读取多个Oracle数据块的数据,它是一次顺序读取.当然,在我们想到磁盘时,也会习惯于随机访问(random access)这个概念. 在一个有合理设计的索引的查询中,SQL 语句通常会使用随机访问来完成单块读取(single block read)调用.

然而,如果你曾经读过任何关于Oracle等待事件的内容,都会发现db file sequential read是用来表示随机读取(例如,索引扫描),db file scattered read是用来表示顺序读取(例如,全表扫描). Oracle使用这个术语表示确实不是很直观. 这使得部分猜测Oracle的事件命名是一种不经意的向后兼容命名. 嗯,这个理论很有意思,不过事实不是这样. 这些事件之所以如此命名确实有个很好的理由.

事件名db file sequential read与db file scattered read描述的是如何将数据块存储到内存中的,而不是如何从磁盘进行读取. Oracle对这两个事件的命名类似于Unix对两类读取调用的命名,函数read()与readv()是其中的代表. Unix的read()函数读取文件中的一段连续的内容,并将数据的不同片段存储到不同的内存区域,此区域由一个内存应用数组所支配. 由类似于read()调用执行的Oracle磁盘读被记录为db file sequential read事件,由类似于readv()调用执行的磁盘读被记录为db file scattered read 事件.

Oracle读取事件的命名理由

如果填充磁盘读取的内容的内存是连续的,发生的磁盘读就是db file sequential read.

  • Oracle 为所有的单块读取生成db file sequential read事件.Oracle始终将单个数据块存储在单个缓存缓冲块(cache buffer)中,因此单块读取永远不会产生db file scattered read事件.
  • 在Oracle 7.3以及后期版本中,当一个独占进程从磁盘中读取临时段时,Oracle会产生多块(multi-block) db file sequential read事件. Oracle早期版本会使用db file scattered read读取临时段的数据到数据库的高速缓冲池. 更新的版本发现临时段的数据几乎无法被共享或被重新访问到,因此就将其直接读取到服务器进程的程序全局区(PGA, Program Global Area)中了.

当填充从磁盘读取的数据的内存的连续性无法被保证的时候,发生的磁盘读就是db file scattered read. 为了填充一次read()调用读取的数据,Oracle内核可能要花费更多的时间来寻找一组连续的内存.只有当read()调用于readv()调用相对readv()调用的速度优势足够抵消这部分额外的时间消耗时,使用这种方式才会有净收益. 找到连续缓冲块(buffer)的代价可能远远超过read()调用相对于readv()调用带来的好处,推动Oracle的内核开发者选择了他们现在使用的这种算法.

Magician
Magician

Figma插件,AI生成图标、图片和UX文案

下载
  • 在大部分情况下,全表扫描与快速全索引扫描都会产生一次或多次db file scattered read. 不过,有时,这些扫描只会产生db file sequential read.

例如: 从一个Oracle跟踪文件摘录的如下片段显示,一个全表扫描仅仅使用到了db file sequential read. 这个表存储在文件2的块2到20的连续块中,它的高水位线在第16个块上. 数据库的块大小(block size)是8KB. 由于在此查询执行之前,所有的偶数块都已经存在于数据库高速缓冲池(buffer cache)中,这次扫描的读操作全都是单块读取.

01 PARSING IN CURSOR #1 len=31 dep=0 uid=18 oct=3 lid=18 tim=26532087 hv=2854987545 ad='82061e04'

02 select count(1) from test_tab

03 END OF STMT

04 PARSE #1:c=0,e=0,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=4,tim=26532087

05 EXEC #1:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4,tim=26532087

06 WAIT #1: nam='db file sequential read' ela= 0 p1=2 p2=3 p3=1

07 WAIT #1: nam='db file sequential read' ela= 0 p1=2 p2=5 p3=1

08 WAIT #1: nam='db file sequential read' ela= 0 p1=2 p2=7 p3=1

09 WAIT #1: nam='db file sequential read' ela= 0 p1=2 p2=9 p3=1

10 WAIT #1: nam='db file sequential read' ela= 0 p1=2 p2=11 p3=1

11 WAIT #1: nam='db file sequential read' ela= 0 p1=2 p2=13 p3=1

12 WAIT #1: nam='db file sequential read' ela= 0 p1=2 p2=15 p3=1

13 FETCH #1:c=1,e=1,p=7,cr=14,cu=3,mis=0,r=1,dep=0,og=4,tim=26532088

下面这些来自Solaris truss命令的输出结果展示了这个查询执行的系统调用.第23行到27行展示了文件是如何打开,以及如何以文件句柄409进行引用的.第31行显示了一次pread()系统函数的调用,除了不会与read()一样移动文件指针外,pread()的行为与read()完全一致,它接收文件偏移量作为它的第四个参数.它的返回值是成功读取的字节的大小. 由于timed_statistices实例参数为true, times()调用提供了计时信息.

01 *** SUID: ruid/euid/suid = 4076 / 108 / 108 ***

02 read(10, 0x010ACACE, 2064)  (sleeping...)

03 read(10, "\097\0\006\0\0\0\0\003 ^".., 2064) = 151

04 times(0xEFFFE360)   = 162380015

05 times(0xEFFFDA80)   = 162380015

06 times(0xEFFFD9C0)   = 162380015

07 times(0xEFFFD9C0)   = 162380015

08 time()  = 948902570

09 brk(0x010E9A60) = 0

10 brk(0x010EBA60) = 0

11 brk(0x010EBA60) = 0

12 brk(0x010EDA60) = 0

13 times(0xEFFFD9C0)   = 162380015

14 times(0xEFFFD9C0)   = 162380015

15 times(0xEFFFC4A0)   = 162380015

16 times(0xEFFFC4A0)   = 162380015

17 time()  = 948902570

18 times(0xEFFFD7A8)   = 162380015

19 times(0xEFFFD760)   = 162380015

20 times(0xEFFFC5D8)   = 162380015

21 times(0xEFFFC578)   = 162380015

22 times(0xEFFFBE90)   = 162380015

23 open64("/home/jeffh/test/data/tools01.dbf", O_RDWR|O_DSYNC) = 15

24 getrlimit(RLIMIT_NOFILE, 0xEFFFBE98)    = 0

25 fstat64(409, 0xEFFFBE00)    Err#9 EBADF

26 fcntl(15, F_DUP2FD, 0x00000199) = 409

27 close(15)   = 0

28 fcntl(409, F_SETFD, 0x00000001) = 0

29 ioctl(409, 0x0403, 0xEFFFBE5C)  Err#25 ENOTTY

30 times(0xEFFFBE48)   = 162380016

31 pread(409, "0602\0\0\080\003\0\0 + B".., 8192, 24576) = 8192

32 times(0xEFFFC530)   = 162380016

33 times(0xEFFFC5D8)   = 162380016

34 times(0xEFFFC5D8)   = 162380016

35 times(0xEFFFC5D8)   = 162380016

36 times(0xEFFFC578)   = 162380016

37 pread(409, "0602\0\0\080\005\0\0 + V".., 8192, 40960) = 8192

38 times(0xEFFFC530)   = 162380016

39 times(0xEFFFC5D8)   = 162380016

40 times(0xEFFFC5D8)   = 162380016

41 times(0xEFFFC5D8)   = 162380016

42 times(0xEFFFC578)   = 162380016

43 pread(409, "0602\0\0\080\007\0\0 + V".., 8192, 57344) = 8192

44 times(0xEFFFC530)   = 162380016

45 times(0xEFFFC5D8)   = 162380016

46 times(0xEFFFC5D8)   = 162380016

47 times(0xEFFFC5D8)   = 162380016

48 times(0xEFFFC578)   = 162380016

49 pread(409, "0602\0\0\080\0\t\0\0 + V".., 8192, 73728) = 8192

50 times(0xEFFFC530)   = 162380016

51 times(0xEFFFC5D8)   = 162380016

52 times(0xEFFFC5D8)   = 162380016

53 times(0xEFFFC5D8)   = 162380016

54 times(0xEFFFC578)   = 162380016

55 pread(409, "0602\0\0\080\0\v\0\0 + V".., 8192, 90112) = 8192

56 times(0xEFFFC530)   = 162380016

57 times(0xEFFFC5D8)   = 162380016

58 times(0xEFFFC5D8)   = 162380016

59 times(0xEFFFC5D8)   = 162380016

60 times(0xEFFFC578)   = 162380016

61 pread(409, "0602\0\0\080\0\r\0\0 + V".., 8192, 106496) = 8192

62 times(0xEFFFC530)   = 162380016

63 times(0xEFFFC5D8)   = 162380016

64 times(0xEFFFC5D8)   = 162380016

65 times(0xEFFFC5D8)   = 162380017

66 times(0xEFFFC578)   = 162380017

67 pread(409, "0602\0\0\080\00F\0\0 + V".., 8192, 122880) = 8192

68 times(0xEFFFC530)   = 162380017

69 times(0xEFFFC5D8)   = 162380017

70 times(0xEFFFC5D8)   = 162380017

71 times(0xEFFFDB40)   = 162380017

72 times(0xEFFFE3A8)   = 162380017

73 write(13, "\0B0\0\006\0\0\0\0\010\0".., 176) = 176

74 read(10, "\0 y\0\006\0\0\0\0\003 ^".., 2064) = 121

75 times(0xEFFFE360)   = 162380017

76 times(0xEFFFDA80)   = 162380017

77 times(0xEFFFDB40)   = 162380017

78 times(0xEFFFE3A8)   = 162380017

79 times(0xEFFFE360)   = 162380017

80 lseek(14, 37376, SEEK_SET)  = 37376

81 read(14, "\0\v04E2\0\0\0 J04E3\0\0".., 512) = 512

82 times(0xEFFFE3A8)   = 162380017

83 write(13, "\0 U\0\006\0\0\0\0\004\0".., 85) = 85

84 read(10, 0x010ACACE, 2064)  (sleeping...)

下表描述了Oracle产生db file sequential readdb file scattered read事件的相关情况.

Oracle 事件 产生单块读取事件的操作(p3=1) 产生多块读取事件的操作(p3>1)
db file sequential read 索引扫描,
在区间内跳过块进行读取的全表扫描,
根据rowid进行的表访问等
临时段读取
db file scattered read 绝对不会 全表扫描,快速全索引扫描等.

引用:
HOLT, JEFF. 2000. “Predicting Multi-Block Read Call Sizes,” Hotsos Journal, (Jan. 2000): 8–9. http://www.hotsos.com.

Jeff Holt是位于得克萨斯州盐湖城的Hotsos LLC公司的一位系统性能优化专家.

No related posts.

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
clawdbot ai使用教程 保姆级clawdbot部署安装手册
clawdbot ai使用教程 保姆级clawdbot部署安装手册

Clawdbot是一个“有灵魂”的AI助手,可以帮用户清空收件箱、发送电子邮件、管理日历、办理航班值机等等,并且可以接入用户常用的任何聊天APP,所有的操作均可通过WhatsApp、Telegram等平台完成,用户只需通过对话,就能操控设备自动执行各类任务。

19

2026.01.29

clawdbot龙虾机器人官网入口 clawdbot ai官方网站地址
clawdbot龙虾机器人官网入口 clawdbot ai官方网站地址

clawdbot龙虾机器人官网入口:https://clawd.bot/,clawdbot ai是一个“有灵魂”的AI助手,可以帮用户清空收件箱、发送电子邮件、管理日历、办理航班值机等等,并且可以接入用户常用的任何聊天APP,所有的操作均可通过WhatsApp、Telegram等平台完成,用户只需通过对话,就能操控设备自动执行各类任务。

12

2026.01.29

Golang 网络安全与加密实战
Golang 网络安全与加密实战

本专题系统讲解 Golang 在网络安全与加密技术中的应用,包括对称加密与非对称加密(AES、RSA)、哈希与数字签名、JWT身份认证、SSL/TLS 安全通信、常见网络攻击防范(如SQL注入、XSS、CSRF)及其防护措施。通过实战案例,帮助学习者掌握 如何使用 Go 语言保障网络通信的安全性,保护用户数据与隐私。

8

2026.01.29

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

566

2026.01.28

包子漫画在线官方入口大全
包子漫画在线官方入口大全

本合集汇总了包子漫画2026最新官方在线观看入口,涵盖备用域名、正版无广告链接及多端适配地址,助你畅享12700+高清漫画资源。阅读专题下面的文章了解更多详细内容。

208

2026.01.28

ao3中文版官网地址大全
ao3中文版官网地址大全

AO3最新中文版官网入口合集,汇总2026年主站及国内优化镜像链接,支持简体中文界面、无广告阅读与多设备同步。阅读专题下面的文章了解更多详细内容。

345

2026.01.28

php怎么写接口教程
php怎么写接口教程

本合集涵盖PHP接口开发基础、RESTful API设计、数据交互与安全处理等实用教程,助你快速掌握PHP接口编写技巧。阅读专题下面的文章了解更多详细内容。

11

2026.01.28

php中文乱码如何解决
php中文乱码如何解决

本文整理了php中文乱码如何解决及解决方法,阅读节专题下面的文章了解更多详细内容。

16

2026.01.28

Java 消息队列与异步架构实战
Java 消息队列与异步架构实战

本专题系统讲解 Java 在消息队列与异步系统架构中的核心应用,涵盖消息队列基本原理、Kafka 与 RabbitMQ 的使用场景对比、生产者与消费者模型、消息可靠性与顺序性保障、重复消费与幂等处理,以及在高并发系统中的异步解耦设计。通过实战案例,帮助学习者掌握 使用 Java 构建高吞吐、高可靠异步消息系统的完整思路。

11

2026.01.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
SQL 教程
SQL 教程

共61课时 | 3.6万人学习

Java 教程
Java 教程

共578课时 | 52.9万人学习

oracle知识库
oracle知识库

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号