SQL语句的处理(SQL processing)
一、SQL语句的解析
当应用程序向服务器发送SQL语句的时候,也就是parse call,服务器会在PGA中打开一个cursor(该cursor会有一个handle指向SGA中的private SQL area)来保存该SQL语句.
1、syntax check(语法检查):检查SQL语句的语法是否完整;
2、semantic check(语义检查):检查其中的对象是否有意义,比如说是否存在,用户是否有足够的访问权限等;
3、Shared Pool Check(共享池检查):检查是否有相同的语句存在于共享池中,选择是进行软解释还是硬解析;
ORACLE数据库会根据SQL语句的文本,利用内部的散列算法,产生一个散列值(hash value)(只要SQL文本逐个字逐个字一模一样,则算法产生的散列值就一样),该散列值就是SQL ID。如果该散列值与共享内存中的散列值一样,说明存在相同的SQL语句。此时,ORACLE数据库就会利用现有的执行计划和生成树(也就是library cache hit),这就是软解析。否则,就要进行硬解析(也叫library cache miss)。
对于硬解析,ORACLE数据库需要产生一个新的应用程序代码。期间,需要多次访问library cache和data dictionary cache去检查数据字典。访问到特定对象的时候,会使用latch来锁定指定的对象,会一定程度上降低并发性。DDL语句总是要进行硬解析。
需要区别的是,SQL语句的内存地址(数据库利用SQL ID进行逐字匹配的时候,数据库会分配一个内存地址)和执行计划散列值(一个SQL ID有可能对应多个执行计划)
4、SQL Optimization
5、SQL Row Source Generation
row source generator会接收从优化器传送过来的执行计划,生成一个迭代计划,也就是query plan.该query plan由多个步骤组成,每个步骤都会产生row set.该row set可以被下一步使用或者最后一步使用,而row source可以是表、视图或者连接、分组操作。 row source generator会产生一个row source tree(如下)(其需要从底部往上读)。
6、Excution
按照row source tree执行,期间若SGA中没有相应的数据块,则数据库需要从磁盘中读入数据块到SGA中。之后,ORACLE会记录所有的变化到日志,释放所占的所有lock和latch,返回结果给用户,关闭cursor.
二、DDL语句的执行
由于DDL语句是在数据字典中定义一个对象,所以DDL语句的处理跟DML语句有很大的不同。DDL语句必须进行硬解析,而且需要执行很多递归的SQL语句来执行DDL语句。以创建一个表为例,简述DDL语句的递归过程:
- 执行DDL语句前,先执行一个commit语句;
- 确定用户是否拥有执行该DDL语句的权限;
- 确定所建的表应该放在哪个表空间;
- 确定表空间的配额是否超出;
- 确定该表在数据字典中没有同名的;
- 往数据字典中插入表信息的数据行;
- 执行commit或rollback语句;
---------------------------------------------------------------------------------------------------
如有错误,欢迎指正