第一部分 . 一条SQL语句的旅行之路
你可以在任意一个client执行一条sql statement,但是这条sql statement是如何被解析,执行,最后再把结果返回到client的呢。下面我们就一起来体验一下sql statement的旅行之路。
一、 发送sql语句
1. 发送请求
如果你是通过网络连接到server端的数据库的话。在client发送一条sql statement,首先要通过user process向server端发送请求(serving naming服务)向server发送请求。是如何通过serving naming服务向server发送请求的呢?
Serving nameing的配置可以 通过查看tnsnames.ora文件了解。
[oracle@lzc admin]$ cat tnsnames.ora
# tnsnames.ora Network Configuration File: /u01/app/oracle/product/10.2.0.1/db_1/network/admin/tnsnames.ora
# Generated by Oracle configuration tools.
LZCDB =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.5.5.11)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = lzcdb)
)
)
红色标记的为server端数据库的的服务名,在8i之前都是使用SID。
一个数据库可以有多个服务名,它通过监听对外提供服务。就是说首先服务名得被注册到监听中之后才能被client连接。
可以在sqlplus中执行以下命令查看数据库的服务名,和添加服务名
SQL> show parameter service_name
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
service_names string dblzc
修改服务名
SQL> alter system set service_names='dblzc,dblzc_test';
System altered.
2. 与server process建立连接
当client向server发送请求的时候,server端的监听会分析client请求的数据库service name。当监听找到请求的数据库之后,系统会启动server process与user process进行连接。到此,监听对于已经与serverdatabase建立连接之后的session就没有作用了。后面的任务就有server process全权负责了
二、 处理sql语句
到了server process这都做了什么呢?
Oracle的server process有oracle自动创建,用来处理连接到实例的用户进程发出的请求。对于专用服务器模式,user process和server process是一一对应的,而在共享服务器莫斯下,一个oracleserver process程可以同时服务多个user process。
Server process主要的任务就是:
3. 解析、执行用户提交的sql语句
Server process会对用户提交的数据进行解析和执行,那它又是在何处完成这些工作的呢?
这里就要谈到oracle的内存结构中的PGA,PGA像server process的办公室和工作站一样,相当于server process的专用内存区域。PGA保存着server process进程的数据和控制信息。
a) 查看执行计划是否已存在
当一条sql语句在执行之前,server process会先到shared pool中的Library Cache中搜索,看看是否有相同的sql语句被解析、执行过,如果能找到,那么oracle就可以直接利用Library Cache中的存储的执行计划来执行,这个过程有一个专业的名词叫做软解析。这样就可以省去,再重新进行解析,制定执行计划的麻烦增大sql语句的执行效率。若没有找到,就必须重新解析,这个过程也有个专业名称叫做硬解析。
这里说明一下,shared pool分为Library Cache、Dictionary Cache等几个部分组成。Library Cache中主要存放用户执行的SQL和PL/SQL语句,oracle设计Dictionary Cache的目的就是为了执行过的语句能被重用。
b) 读取相关数据
当解析、制定完执行计划之后,是不是就要从数据文件中直接检索数据了呢?当然,先不要着急。
在从数据文件中直接检索数据之前会先从SGA中的data buffer cache中查找,看所要请求的数据是否在内存中已经存在。如果已经存在则直接从data buffer cache中读取数据,这样就就不需要再重新从数据文件中检索数据,提高了sql的执行速度。
若data buffer cache中并未保存该语句请求的数据,则server process会从数据文件中重新读数据。将数据复制到data buffer cache中,另外会复制一份镜像到undo段中用一致性查询,以及事务回退等。数据加载到data buffer cache中被放入那个缓冲池是由对象的存储属性决定的,可以再存storage存储参数子句中指定对象加载到内存时存放的缓冲池类型。
CREATE TABLE TEST(id number)STORAGE(BUFFER_POOL KEEP);
譬如这条语句就创建了一个TEST的表存放在缓冲池中大的keep池。
4. 返回执行结果
最后当server process完成了对数据的一列的操作之后会把结果返回到client。至此,这条sql语句,就算基本完成了它的整个旅途。