15、物理IO_1
物理读(physical read)
数据实际存储在磁盘上,将数据从磁盘上读取到内存里,就叫做物理读
将修改完的数据从内存写到磁盘,叫做物理写
一般我们关注的主要是物理读
IOPS(或者TPS):每秒读的次数(主要关注的)
IO throughart:IO吞吐量(每秒多少M)
数据文件
数据文件分为两类:
1、临时数据文件(temporary file),可以有多个
2、普通数据文件
物理读过程图示:
图解:
用户连接上数据库,发送一个SQL,server process接到SQL以后解析SQL,解析完了以后生成执行计划,然后按照执行计划去执行,这时候它就要访问数据,按照SQL的执行计划,要去访问某一个数据块,访问这个数据块的数据行,而这个数据在磁盘的一个数据块里面(首先在buffer cache里面找,找找找,在buffer里面没找到,它就从磁盘上找,在磁盘上的一个块里找到了),找到以后,它要从磁盘上读取到buffer里面去,IO的最小单位是block(8k),所以最小要读8k数据到buffer里面去,再从buffer里面取出来放到PGA里面去,再从PGA里面处理完之后,再返给用户
现在一般的存储,一个物理读,正常情况,所耗费的时间:小于2ms (最小不要小于8ms,oracle官方认为小于20ms就是正常的)
物理读的种类
1、单块读:每次读取磁盘里的一个块到buffer cache里去(走索引的时候)
2、多块读:每次读取多个块(全表扫描的时候)
这两个也被合成一个物理读种类,都是从磁盘读取到内存,再从内存返给用户
3、直接路径读(direct path read):数据从磁盘直接读取到PGA,不经过内存,然后PGA返给用户(比如oracle的备份、lob对象:就是数据库里存储着的照片的情况,以blob大对象的方式存储的,读取照片一般不会读取到内存再读取出来,一般都是直接读取出来的,因为占用内存太大,照片一般也不会出现经常读的情况)
4、发生磁盘排序(临时文件的直接路径读写):在读取数据的时候,从磁盘读取到buffer里,再从buffer里面读取到PGA里面去,这时候还需要排序,但是PGA的最大大小只有200M,也有可能没有200M,要排序,排序的数据量好大,这时候PGA就排不开了,它就把这些数据先临时写到临时文件里面去,然后一块块,排完以后,再从临时文件里面读取到PGA里面去,这时候也产生IO了
磁盘(存储),它不害怕一次性读取多个块到内存,它最害怕的是:读取的多个块分布在不同的位置(读取多次)
有几种情况它会影响多块读的块数
1、dbfile mostblock readcount参数的影响:假设这个参数我们设置为6,oracle在多块读的时候,每次最多读取6块
2、数据连续分布:数据块之间有间隔(分布不连续),它就要分多次读取
如图,读取4次
3、内存已有的时候
如图,读取5次
4、吞吐量
通过索引来访问表,第一:它是单块读;第二:它是有顺序的;所以我们给它起了一个名字:dbfile sequential read(数据文件顺序读)
全表扫描,oracle读取数据的时候,不是按照顺序读的,而是随机读取的,是哪个块离磁头最近先读哪个块,以最快的速度读取到内存里,所以我们给它起了一个名字:dbfile scotteced read(数据文件随机读)
等待事件(wait event)
用户发送一个SQL,server process接收到SQL以后需要解析:
1、parse解析时间(花费CPU)
2、执行SQL,访问数据的时间,
第一种情况:数据在内存里(花费CPU)
第二种情况:数据在磁盘上(花费IO)
3、网络时间
4、排序时间
5、锁(释放锁的时间)
......
1、2、3、4、5......就构成了这个SQL的执行时间
SQL的执行时间图示:
图解:
假设SQL的执行时间是1s,现在我们想要把它缩短为80ms,速度更快一些,就需要把其中的一些时间去掉,这时候就需要知道整个SQL的执行时间都花在了谁的上面,要知道在哪些上产生了等待时间,哪些花费CPU时间,然后去掉等待时间,进行优化
因此我们需要知道:
1、一个SQL在从头到尾的执行过程中,确实会产生等待;
2、这些等待被计算到了SQL的执行过程中,影响SQL执行的时间;
3、在SQL的执行过程中,到底产生了哪些等待,等待的时间是多少,产生了多少次,什么类型,oracle会记录存储下来,然后我们就可以去查
等待事件的类型:
1、IO相关的(比如单块读、多块读)
2、与网络相关的
3、锁相关的等等
内存读(memory read)
内存读两种情况:
1、直接内存读
2、先物理读然后再内存读
内存读的另外两种情况:
1、select会产生内存读,这种内存读我们叫做:consistency read(一致性内存读),也叫作:cr
2、DML(增删改)也会产生内存读,这种内存读我们叫做:current read(当前内存读),也叫作:cu
select内存读和DML内存读是分开的,DML内存读消耗的资源比select内存读要高