Oracle中SQL解析整体过程

Oracle数据库体系结构

数据库服务器构成

1)由Oracle实例和Oracle数据库组成
2)Oracle实例:包含SGA和后台进程
3)Oracle数据库结构:内存,进程,存储

内存

目前共有6大内存
1)共享池:缓存最近执行过的sql语句,以及执行计划,避免硬解析
2)数据库缓冲区高速缓存:缓存oracle访问的数据块,避免磁盘i/o
3)重做日志缓存区:用于处理日志的
4)大型池:oracle需要比较大的内存时会用到,备份恢复或者并行处理等
5)Streams池:用于streams复制
6)Java池:java类编译时会用到

进程

1)用户进程:数据库用户请求连接oracle时启动(配合监听进程去访问远端的数据库)
2)服务器进程:连接oracle时使用,用户建立会话时启动
3)后台进程:启动oracle实例时启动。
	后台进程主要包括四种:
	a.系统监视器SMON:
	b.进程监视器PMON:
	c.数据库写进程DBWn:将信息从SGA的数据库缓冲存储区中写入到数据库数据文件中
	d.日志写进程LGWR:会重做日志文件,并执行归档进程ARCn,完成归档日志文件

存储

1)控制文件:记录数据库的物理结构信息、当前运行的状态信息等
2)数据文件:Oracle表信息
3)联机重做日志文件:记录数据文件块所有的操作变化过程。
4)参数文件
5)备份文件
6)口令文件
7)归档日志文件
8)预警和跟踪日志文件

附图:附加一张Oracle Concepts Guide中给出的图
在这里插入图片描述

表空间,数据块,数据库

表空间

1)SYSTEM和SYSAUX表空间是必须存在的表空间
2)以上俩个表空间在创建数据库时创建的,且必须联机
3)SYSTEM表空间用于核心功能(数据字典),SYSAUX表空间用于附加的数据库组件
4)一个表空间包含多个数据文件
5)一个数据文件仅归属一个表空间

段,区,块

1)段存在于表空间
2)段由区的集合构成
3)区是数据块的集合
4)数据块映射到磁盘块

灰数据

在数据库缓冲区中对数据块增删改查,当DBWn写入到数据块时,出现问题,
导致SGA中数据库缓冲区中的数据块记录和数据快文件不一致导致灰文件。

在这里插入图片描述

Sql执行过程

客户端将sql语句发到服务器进行解析

客户端的用户使用进程将sql传递到服务器,服务器进程PGA将sql传递到后台进程,使之进行操作。

检查SQL语句的合法性

对SQL语句进行语法检查,看其是否符合语法规则。
如果服务器进程认为这条SQL语句不符合语法规则时,会把这个错误信息,反馈到客户端,展现给用户。
在整个过程中不会对SQL中的表名和列名进行检查。

检查SQL语言含义

若SQL语句符合语法规则,则服务器进程接下来会对语句中的字段、表等内容进行检查。
看字段、表是否在数据库中。
如果表名与列名不准确的话,会把这个错误信息,反馈到客户端,展现给用户。

获得对象解析锁

当语法、语义都正确后,系统会对需要查询的对象进行加锁。
主要是为了保证数据的一致性,防止我们在操作的过程中,其他用户对这个对象的结构发生改变。

数据访问权限的核对

当前面几步完成之后,服务器进程还会检查,所连接的用户是否有这个数据访问的权限。

对sql语句进行解析(软解析和硬解析)

软解析:将用户输入的SQL进行HASH运算和共享池中的HASH值对比,相同即直接运行。
硬解析:将用户输入的SQL进行HASH运算和共享池中的HASH值对比,不相同则执行7,8,9步。
1)验证SQL语句是否完全一致:
	Oracle会对传递进来的SQL语句使用HASH函数运算得出HASH值,并于共享池中的HASH值进行对比。
如果SQL语句的HASH值和共享池中的某个HASH值一致,那么ORACLE事实上还需要对SQL语句的语义进行再次检测,以决定是否一致,此时为了防止不同用户所导致sql语句不相同。
现有数据库中SQL语句的HASH值,可以通过访问v$sql、v$sqlarea、v$sqltext等数据字典中的HASH_VALUE列查询得出。
	注意:查询v$sql_shared_cursor可以得知SQL为何不能共享的原因,语句如下:
		语句:select address,auth_check_mismatch,translation_mismatch,optimizer_mismatch from v$sql_shared_cursor where address in ( select address from v$sql where upper(sql_text) like 'SELECT * FROM EMP%' )  
		参数1:AUTH_CHECK_MISMATCH 表示对同样一条SQL语句转换是不匹配的。
		参数2:TRANSLATION_MISMATCH 表示SQL游标涉及到的数据对象是不同的。
		参数3:OPTIMIZER_MISMATCH 表示会话的优化器环境是不同的。

2)验证SQL语句执行环境是否相同:
	验证SQL语句执行环境是否一样。
	通过上面的检查以后,如果SQL语句是一致的,那么就会重用原有SQL语句的执行计划和优化方案,也就是软解析。
	如果SQL语句没有找到同样的SQL副本,那么就需要进行硬解析了,也就是需要进行下面的操作。

3)解决硬解析的最好办法就是绑定变量
	(1)使用了Bind Var能提高性能主要是因为这样做可以尽量避免不必要的硬分析(Hard Parse)而节约了时间,同时节约了大量的CPU资源。
	(2)当一个Client提交一条Sql给Oracle后,Oracle 首先会对其进行解析(Parse),
		然后将解析结果提交给优化器(Optimiser)来进行优化而取得Oracle认为的最优的Query Plan,
		然后再按照这个最优的Plan来执行这个Sql语句(当然在这之中如果只需要软解析的话会少部分步骤)。
	(3)但是,当Oracle接到 Client提交的Sql后会首先在共享池(Shared Pool)里面去查找是否有之前已经解析好的与刚接到的这一个Sql完全相同的Sql,
		当发现有相同的以后解析器就不再对新的Sql在此解析而直接用之前解析好的结果了。
		这里就节约了解析时间以及解析时候消耗的CPU资源。尤其是在OLTP中运行着的大量的短小Sql,效果就会比较明显了。

确定最佳执行计划

当上面的步骤都完成以后,并且没有在共享池找到对应的SQL副本,那么就会进入硬解析,也就是此步骤,
首先会对SQL语句进行优化,但是这个优化是有限度的,远没有工程师对SQL优化的程度大,所以每当开发完成,数据库的优化就显得极为重要。
当服务器进程的优化器确定这条查询语句的最佳执行计划后,会将这条SQL语句与执行计划保存到共享池的库缓存(library cache)中。
后面还有这个查询时,就会省略上面的语法、语义与权限检查的步骤,而直接执行SQL语句,提高SQL语句处理效率。

SQL语句执行(exec)

SQL语句解析是为了确保服务器可以知道这条语句在表达什么意思。
等SQL语句解析完成以后,数据库服务器进程会真正执行这条SQL语句。
一般执行分为俩种情况:
	第一种:若需要使用的数据块已经被读取到数据缓冲区的话(也就是上文提到的数据库缓冲区高速缓存),则服务器进程会直接把这个数据传递给客户端,而不是从数据库文件中去查询数据。
	第二种:若数据不在缓冲区中,服务器进程将从数据库文件中查询相关数据,并且把这些查到的数据放入到数据缓冲区中。
Oracle数据库中,定义了很多种类的高速缓存。例如上面提到的SQL语句缓存(共享池)与现在说的数据缓存(数据库缓冲区高速缓存)。

提取数据(fetch)

当语句执行完成之后,查询到的数据还是在服务器进程中,
所以在服务器端的进程中,有一个专门负责数据提取的一段代码,把查询到的数据结果返回给用户端进程,从而完成整个查询动作。

总结

执行计划这块我会专门总结一篇文章,因为这部分知识带你比较多而且灰常重要。
总结的可能有不到位的地方或者错别字各位大佬多多见谅,至于排版我会尽快改善。
^_^
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值