解析
数据文件:
1、临时文件
2、系统文件(system file):(放着字典表,字典表里记录着数据(数据库自身的信息):数据库里有多少表,有多少列,数据库里有多少用户,用户之间的一些权限是什么,数据库有多少对象,对象的名字,还有表和索引的统计信息等等)
3、普通文件(放着一张张表)
system file的存储格式:也被格式化为一个一个的block
图解:
用户发送一个SQL,然后server process接到并解析,生成执行计划,这些主要是消耗CPU资源,也消耗部分IO资源,解析生成执行计划以后,oracle会把这个SQL文本以及SQL对应的执行计划放到shared pool里面去;
shared pool分为三个部分:library cache、free空间、row cache,将来library cache需要的时候可以从free里面要,row cache需要的时候可以从free里面要,然后随着时间的推移,library cache用不了那么多,它就会释放出来给free,row cache也一样,也会释放出来给free;
library cache:可以暂时认为library cache里面缓存着oracle消耗资源解析完以后的SQL文本以及SQL对应的执行计划,缓存的目的是:当第二个用户执行同一条SQL,或者这条SQL第二次执行时,首先SQL要解析,oracle会先在library cache里面找,这条SQL有没有被解析过,如果解析过了,它就再一次按照之前解析出来的执行计划执行,以减少解析的过程,减低资源的消耗,它就不发生硬解析,发生软解析;如果这条SQL没有被解析过,它就要发生硬解析
硬解析(hard parse)
硬解析的前提是:SQL以及SQL对应的执行计划在library cache里面找不到,server process才会对这个SQL做硬解析
图解:
对于一个SQL(硬解析要做的第一件事:访问字典信息),硬解析要做哪些事情呢(server process要获取到的信息):
例如SQL:select name from t where id = 5;
1、判断SQL语句的语法是否正确
2、判断t表是否存在,t表上有没有name这个列,有没有id这个列
3、判断id列上有没有索引
4、假设当前以HR用户登录数据库,判断HR用户下有没有这个t表,HR用户有没有权限访问t表
5、查询t表的统计信息:t表有多少行,有多少列,id列的选择性是多少,选择性高不高,id列的唯一值数量是多少,id列的集群因子是多少,id列上有没有柱状图啊,有没有数据倾斜啊等等相关的信息
server process要获取到上述信息,才能进行下一步,这些信息存储在system file的数据字典表里面
硬解析:
1、访问字典信息 -> 递归SQL(消耗的资源很小)
2、列出SQL所有的执行路径,以及执行方式,然后根据统计信息,估算每一个执行路径的cost成本,然后选择其中最优的执行路径作为执行计划,然后把SQL以及对应的最优的执行路径缓存到library cache里去(最消耗资源)
递归SQL
递归SQL:
要硬解析一个SQL,需要从字典表里面把相关信息获取出来,从表里获取数据就要去执行一个SQL,这个SQL访问的是字典表,这个SQL,我们叫做递归SQL
递归SQL访问的是:字典表
图解:
递归SQL访问字典表,把数据从字典表里面取出来放到buffer里去,然后把需要的10行数据(比如需要的数据是10行,buffer是100行)放到row cache里去,然后就可以解析SQL了
row cache 也叫dick cache(字典缓存)
row cache的特点:
1、它里面放的是字典信息
2、它以行的形式存在着
软解析(soft parse)
图解:
oracle在library cache里面找到了要执行的SQL在library cache里面有,已经被解析过缓存在library cache里了,这时候,oracle就按照SQL的执行计划去执行了吗?没有:
这时候,oracle会做一件事:针对当前登陆的用户(比如HR用户),它要去判断HR用户对t表、name列、id列有没有访问权限,如果没有权限,这个SQL就不能执行;有权限,它就使用这个SQL以及对应的执行计划来执行
所以对于软解析来讲:它要通过数据字典来判断当前登陆的用户对t表、name列、id列有没有访问权限
软软解析(soft soft parse)
图解:
用户连接上数据库,在当前的会话里面,用户在一个比较短的时间内,某一个相同的SQL连续执行三次以上:第一次硬解析,第二次软解析,第三次软解析,第四次软软解析;
软软解析是怎么一回事呢:就是在执行一个SQL时候,它连软解析里面要判断权限的那一步都不判断了(不再判断是否有权限),直接按照执行计划去执行
为什么软软解析连权限都不去判断了?
同一个SQL被连续执行三次以上,在当前会话的server process里面的PGA里面,在PGA和library cache之间会建立一个连接,始终保持打开的状态,PGA和library cache会有一种感知的作用,就是一直保持着联系
共享SQL
图解:
例如要执行SQL:select name from t where id = 6;
用户连接上数据库,执行一个SQL,在library cache里面找,在library cache里面没有找到,但是library cache里面有:select name from t where id = 6;的SQL以及执行计划,一个SQL要进行软解析,它的SQL文本以及对应的执行计划必须完全一致,但是这里的SQL:id = 6而不是id = 5,这两个SQL不相同,所以它就不能进行软解析,要发生硬解析;所以需要我们的开发人员,在开发的时候尽量的去实现共享
一个SQL,如果大小写、空格、回车、字面量与缓存在library cache里的SQL有一丁点的不一样,都会导致硬解析
共享SQL的条件
1、统一编码规则(统一书写规则):(比如SQL:select name from t where id = 5;
1、关键字select、from、where必须大写(统一大小写);
2、select的后面加回车(回车的位置);
3、单词之间只加一个空格(空格的数量))
2、在列没有数据倾斜的情况下,在SQL里面列的值不要出现字面值,要使用绑定变量(bind value);如果有数据倾斜,列的值可以使用字面值
只有共享SQL了,才能减少硬解析
DDL、统计信息对执行计划的影响
DDL操作:
对于oracle数据库来说,当你对表里面的某个对象做了DDL操作,这个时候,依赖于这个对象的所有缓存在library cache的SQL以及对应的执行计划都会失效,下次执行这个SQL的时候,就会产生硬解析
统计信息:
假设现在我们收集了一下t表的统计信息,然后跟以前t表的统计信息作比较,发现现在收集的统计信息变化量比较大(比如:以前100万行,现在200万行),这时候,oracle就会让缓存在library cache里面的所有依赖于t表的SQL以及对应的执行计划都失效,然后下次执行SQL的时候,就会产生硬解析,产生硬解析,就可能导致执行计划发生变化
所以,在数据库正常运行的期间,尽量的不要收集统计信息,也尽量的不要做DDL操作
标签:执行,17,cache,library,sql,SQL,解析,id From: https://www.cnblogs.com/xgq20210831/p/18560121