假如我们现在利用Select语句从数据库查询数据Oracle数据库是如何运作的呢?从中我们可以领悟到什么呢?下面就结合一条简单的select语句看看Oracle数据库后台的运作机制这对于我们之后的系统管理与故障排除非常有帮助
第一步客户端把语句发给服务器端执行
当我们在客户端执行select语句时客户端会把这条SQL语句发送给服务器端让服务器端的进程来处理这语句也就是说Oracle客户端是不会做任何的操作他的主要任务就是把客户端产生的一些SQL语句发送给服务器端虽然在客户端也有一个数据库进程但是这个进程的作用跟服务器上的进程作用事不相同的服务器上的数据库进程才会对SQL语句进行相关的处理不过有个问题需要说明就是客户端的进程跟服务器的进程是一一对应的也就是说在客户端连接上服务器后在客户端与服务器端都会形成一个进程客户端上的我们叫做客户端进程;而服务器上的我们叫做服务器进程所以由于所有的SQL语句都是服务器进程执行的所以有些人把服务器进程形象地比喻成客户端进程的影子
第二步语句解析
当客户端把SQL语句传送到服务器后服务器进程会对该语句进行解析同理这个解析的工作也是在服务器端所进行的虽然这只是一个解析的动作但是其会做很多小动作
查询高速缓存服务器进程在接到客户端传送过来的SQL语句时不会直接去数据库查询而是会先在数据库的高速缓存中去查找是否存在相同语句的执行计划如果在数据高速缓存中刚好有其他人使用这个查询语句的话则服务器进程就会直接执行这个SQL语句省去后续的工作所以采用高速数据缓存的话可以提高SQL语句的查询效率一方面是从内存中读取数据要比从硬盘中的数据文件中读取数据效率要高另一方面也是因为这个语句解析的原因
不过这里要注意一点这个数据缓存跟有些客户端软件的数据缓存是两码事有些客户端软件为了提高查询效率会在应用软件的客户端设置数据缓存由于这些数据缓存的存在可以提高客户端应用软件的查询效率但是若其他人在服务器进行了相关的修改由于应用软件数据缓存的存在导致修改的数据不能及时反映到客户端上从这也可以看出应用软件的数据缓存跟数据库服务器的高速数据缓存不是一码事
语句合法性检查
当在高速缓存中找不到对应的SQL语句时则数据库服务器进程就会开始检查这条语句的合法性这里主要是对SQL语句的语法进行检查看看其是否合乎语法规则如果服务器进程认为这条SQL语句不符合语法规则的时候就会把这个错误信息反馈给客户端在这个语法检查的过程中不会对SQL语句中所包含的表名列名等等进行SQL他只是语法上的检查
语言含义检查
若SQL语句符合语法上的定义的话则服务器进程接下去会对语句中的字段表等内容进行检查看看这些字段表是否在数据库中如果表名与列名不准确的话则数据库会就会反馈错误信息给客户端
所以有时候我们写select语句的时候若语法与表名或者列名同时写错的话则系统是先提示说语法错误等到语法完全正确后再提示说列名或表名错误若能够掌握这个顺序的话则在应用程序排错的时候可以节省时间
获得对象解析锁
当语法语义都正确后系统就会对我们需要查询的对象加锁这主要是为了保障数据的一致性防止我们在查询的过程中其他用户对这个对象的结构发生改变对于加锁的原理与方法我在其他文章中已经有专门叙述在这里就略过不谈了
数据访问权限的核对
当语法语义通过检查之后客户端还不一定能够取得数据服务器进程还会检查你所连接的用户是否有这个数据访问的权限若你连接上服务器的用户不具有数据访问权限的话则客户端就不能够取得这些数据故有时候我们查询数据的时候辛辛苦苦地把SQL语句写好编译通过但是最后系统返回个没有权限访问数据的错误信息让我们气半死这在前端应用软件开发调试的过程中可能会碰到所以要注意这个问题数据库服务器进程先检查语法与语义然后才会检查访问权限
确定最佳执行计划
当语句与语法都没有问题权限也匹配的话服务器进程还是不会直接对数据库文件进行查询服务器进程会根据一定的规则对这条语句进行优化不过要注意这个优化是有限的一般在应用软件开发的过程中需要对数据库的sql语言进行优化这个优化的作用要大大地大于服务器进程的自我优化所以一般在应用软件开发的时候数据库的优化是少不了的
当服务器进程的优化器确定这条查询语句的最佳执行计划后就会将这条SQL语句与执行计划保存到数据高速缓存如此的话等以后还有这个查询时就会省略以上的语法语义与权限检查的步骤而直接执行SQL语句提高SQL语句处理效率
第三步语句执行
语句解析只是对SQL语句的语法进行解析以确保服务器能够知道这条语句到底表达的是什么意思等到语句解析完成之后数据库服务器进程才会真正的执行这条SQL语句
这个语句执行也分两种情况一是若被选择行所在的数据块已经被读取到数据缓沖区的话则服务器进程会直接把这个数据传递给客户端而不是从数据库文件中去查询数据若数据不在缓沖区中则服务器进程将从数据库文件中查询相关数据并把这些数据放入到数据缓沖区中
这里仍然要注意一点就是Oracle数据库中定义了很多种类的高速缓存像上面所说的SQL语句缓存与现在讲的数据缓存我们在学习数据库的时候需要对这些缓存有一个清晰的认识并了解各个种类缓存的作用这对于我们后续数据库维护与数据库优化是非常有用的
第四步提取数据
当语句执行完成之后查询到的数据还是在服务器进程中还没有被传送到客户端的用户进程所以在服务器端的进程中有一个专门负责数据提取的一段代码他的作用就是把查询到的数据结果返回给用户端进程从而完成整个查询动作
从这整个查询处理过程中我们在数据库开发或者应用软件开发过程中需要注意以下几点
一是要了解数据库缓存跟应用软件缓存是两码事情数据库缓存只有在数据库服务器端才存在在客户端是不存在的只有如此才能够保证数据库缓存中的内容跟数据库文件的内容一致才能够根据相关的规则防止数据髒读错读的发生而应用软件所涉及的数据缓存由于跟数据库缓存不是一码事情所以应用软件的数据缓存虽然可以提高数据的查询效率但是却打破了数据一致性的要求有时候会发生髒读错读等情况的发生所以有时候在应用软件上有专门一个功能用来在必要的时候清除数据缓存不过这个数据缓存的清除也只是清除本机上的数据缓存或者说只是清除这个应用程序的数据缓存而不会清除数据库的数据缓存
二是绝大部分SQL语句都是按照这个处理过程处理的我们DBA或者基于Oracle数据库的开发人员了解这些语句的处理过程对于我们进行涉及到SQL语句的开发与调试是非常有帮助的有时候掌握这些处理原则可以减少我们排错的时间特别要注意数据库是把数据查询权限的审查放在语法语义的后面进行检查的所以有时会若光用数据库的权限控制原则可能还不能满足应用软件权限控制的需要此时就需要应用软件的前台设置实现权限管理的要求而且有时应用数据库的权限管理也有点显得繁琐会增加服务器处理的工作量因此对于记录字段等的查询权限控制大部分程序涉及人员喜欢在应用程序中实现而不是在数据库上实现