介绍
今天,有同事反馈说是SQL语句执行时间很长,并且得不到结果。于是,我这边在获取到SQL语句后,重新执行并在查询的过程中,查询此SQL语句的等待事件。查询后,我发现该语句执行过程中一直是“db file sequential read”。
解读
参考:https://docs.oracle.com/cd/E11882_01/server.112/e41573/instance_tune.htm#PFGRF94485
从官方文档得知,此等待事件是用户进程正在将buffer读取到SGA buffer cache中,并等待物理I/O调用返回。sequential读取是单块读取。
上面这句话单纯读起来会比较难理解,简单来说就是用户进程正在单块读取磁盘上的DBF数据文件,并将其读入到SGA buffer cache中。这也就意味着,SQL语句需要查询的数据并不能直接在SGA buffer cache中读取到全部的数据,部分数据需要重新从磁盘上的DBF数据文件读入到SGA buffer cache中。如下图所示:
什么情况下会使用单块读呢?
通常情况下,单块读取会发生在使用索引的时候。少数情况下,全表扫描可能会由于extent边界或buffer cache中已存在buffer数据而被截断成单个块读取。
如果想要了解具体的等待信息,可以查询v$session_wait视图的以下字段:
- P1 决对文件号,也就是数据文件的文件编号
- P2 正在读取的数据块
- P3 数据块的数量(应该是1)
对于一个健康的数据库来说,physical read waits应该是继idle waits后最大的等待事件。
注意,对于一个正常的OLTP系统来说,“db file sequential read”等待事件不算是问题。但是,如果SQL语句一直卡在该等待事件上,则可能需要调整SQL语句来避免单块读,或排查磁盘I/O是否出现异常。
评论区