oracle数据库实例(instance)
数据库打开以后,会生成一个内存结构和一堆进程
内存和进程:就是oracle的实例instance
oracle数据库实例结构:
用户是通过连接实例来访问数据库的
shared pool占整个内存的20%
buffer cache占整个内存的80%
redo log buffer占20~100M,一般是100M
各种pool一般占100M
在数据库里,一般数据库的物理内存的50%给oracle,这50%的内存的80%内存给shared pool、buffer cache、redo log buffer、各种pool加起来的一个总和,但是具体情况要根据具体的生产来定
SQL
对于oracle数据库来讲,用户发一个SQL过来,给Oracle数据库,oracle数据库经过执行处理,得到一个结果集,然后返给用户
oracle数据库就是处理SQL,执行SQL的
例如:执行select name from t1 where id = 5;这一条SQL
这是一个SQL文本,对于oracle来说,这个文本显然是不能执行的,
所以对于oracle来说,做的事是:
第一件事是,oracle接收到一个SQL以后,对这个SQL文本进行解析(parse);
第二件事是:解析完了以后,生成一个oracle能认识的,能够照着去执行的SQL执行计划(explain)
第三件事是:oracle照着这个执行计划去执行这个SQL
这个SQL进行解析,生成执行计划,它是要消耗cpu资源的
oracle把SQL语句解析成执行计划,它需要做什么呢?(这个解析包含什么呢?)
1、判断有没有t1这个表,t1表里有没有id这个列,有没有name这个列,这个SQL语法对不对,id列上有没有索引,如果id=5了预计能返回几行数据等等
2、判断完了以后,通过计算生成执行计划
SQL执行计划
执行计划:就是这个SQL要执行的最好的路径(就比如像是导航时的最佳路线)
一条SQL语句一般有多条执行路径,所以解析就需要去判断,去计算哪条是最好的路径,这就需要消耗cpu资源,由于解析需要消耗cpu资源,oracle就会把这个SQL语句和SQL执行计划存到shared pool里
将SQL和SQL执行计划存到shared pool里面有什么好处呢?
下一次一个用户连接上数据库实例以后,执行这个SQL,另外一个用户连接上以后也要执行这个SQL,它就在shared pool里发现,这个SQL对应的执行计划已经被解析过了,这时就不需要像第一个用户第一次执行这个SQL时,执行那么多的解析过程
shared pool里面存着,或者缓存着曾经执行过的SQL,以及SQL对应的执行计划,那么任何一个用户登录到数据库以后,先去shared pool里面找,这个SQL有没有被解析过,shared pool里面有没有这个SQL及对应的执行计划,如果有就不必像第一个用户那样去执行那么多的解析过程
硬解析(hard parse)
第一个用户连接上数据库实例,发送一个SQL给数据库实例,但是在shared pool里面找不到这个SQL及对应的SQL执行计划,就要解析这个SQL,这种解析叫做硬解析
数据库启动以后,随着业务的增加,一段时间稳定以后,数据库的硬解析就非常低了,因为shared pool的作用,一般每秒钟小于5个硬解析,也就是每秒产生新的SQL,解析新的SQL的数量小于5
软解析(soft parse)
第二个用户连接上数据库实例,执行跟第一个用户同样的一条SQL,而在shared pool里面有这个SQL及对应的SQL执行计划,这时候也要解析,这种解析叫做软解析
软解析比硬解析少了好多步骤,所以说,软解析消耗的资源比硬解析消耗的资源少好多
shared pool(共享池)
shared pool的作用:
就是减少硬解析,缓存SQL以及SQL的执行计划来减少硬解析
SQL的执行步骤
1、解析(parse)
2、执行(execute)
3、获取(fetch)
SQL分两类:
1、select(查询、访问数据的)
2、DML(insert、update、delete)涉及到数据修改的
对于oracle来讲,不管是select还是DML都需要解析:
对于DML解析完了,对应的是执行;
对于select解析完了,对应的是获取。
但是一般我们都说SQL的执行步骤都是:解析(parse)---> 执行(execute) ---> 获取(fetch)
datafile(数据文件)
无论是执行还是获取,oracle都会做一件事,就是访问表(表数据),就要访问数据库的datafile文件
图解:
数据库的datafile被格式化成一个一个的block(数据块),block的大小:2K、4K、8K、16K、32K,一般的是:8K;一个block里面存放着多行数据,比如有100行数据
block是IO的最小单位(最小单元)
buffer cache
缓存着表,缓存着block
图解:
buffer cache,oracle也把它格式化成8K大小的一个一个的buffer
用户访问表里的一行数据,这一行数据呢,在一个block里面,这时候oracle会把整个block里面全部的数据行都读取到buffer cache里面去,只需要一行,不管是100行还是多少行,都把整个block加载到buffer里面去
redo log buffer
oracle把整个block里面全部的数据行都读取到buffer cache里面去之后,对其中的一行数据进行修改(insert、update、delete),在内存里面修改,修改完之后,它会对修改的那个动作产生一个日志,记录到redo log buffer里面去;
修改完了之后,马上要提交,提交的时候,又把redo log buffer里面的日志写到数据库的redo log里面去;这时候,在buffer里面被修改的数据就没必要马上写回数据库的datefile里面去了,因为相关的日志已经被保存到redo log里面了,就算这时候数据库突然崩了,被修改过的数据还没被写到磁盘上,被修改的数据没了,等数据库重新启动以后,oracle会使用redo log里面被修改过的数据的日志,自动的再把那一行数据找回来再重新修改回来
所以对于oracle来说,只要日志保存了,被修改过的数据就被保存了
只要对表,对block进行修改,就一定会产生日志;只要提交,日志就会被写到磁盘上,永久保存;只要日志保存了,我们就认为对这个block的修改就永久保存了,因为oracle会自动的对没有从buffer写到block的数据,使用redo log重新恢复过来
redo log buffer的作用:缓存redo log
命中
一个用户要修改或者读取表里的一行数据,但是这一行数据在buffer cache里面没有,这时候就要到磁盘的block里面找,找到之后oracle就把这个block读取到buffer里去,再从buffer里面修改或者读取;然后第二个用户,他也要读取这个表里的另外一行数据,这行数据也在这个block里面,这时候,第二个用户就在buffer cache里面找到了那一行数据,就没有必要再从磁盘上读取,也避免了物理读,这叫做一次命中
命中率
命中率一般可以达到99.9%;假设oracle读一万次buffer,只产生了十次物理读,其余都是内存读
标签:执行,buffer,数据库,讲解,内存,SQL,oracle,解析
From: https://www.cnblogs.com/xgq20210831/p/18551844