一、问题提出
做数据库开发时,常常碰到需要优化的问题,对于一些优化的原因不是很理解。为什么要这么优化、为什么要那么优化。我觉得是缺少对数据库SQL语句处理原理的不理解导致的。通过这个学习能够指导以后的数据库开发写出更高效的代码。
二、SQL语句处理过程(出自concepts)
1)创建游标
游标的创建与SQL语句是相互独立的:任何类型的 SQL 语句执行时都需要创建游标。在大多数应用程序中游标是自动创建的。
2)解析语句
Oracle 还需判断库缓存[library cache]中是否已经存在包含经过解析的与新提交语句相同语句的共享 SQL 区[shared SQL area]。如果存在,则用户进程[user process]使用解析结果立即运行语句(软解析)。如果不存在,Oracle 将生成语句解析结果,用户进程在库缓存中为语句分配共享 SQL 区存储解析结果(硬解析)。与语句执行[execution]相比,解析调用与解析操作是系统开销较高的操作,所以应尽可能地减少此类操作(硬解析)。
a.翻译 SQL 语句,并验证语句的有效性
b.查询数据字典表,检查相关表及数据列的定义
c.获取相关对象上的解析锁[parse lock],确保对象定义不会在语句解析过程中改变(与解析有冲突的 DDL 操作可以打破解析锁)
d.检查访问相关方案对象的权限
e.确定最优的语句执行方案[execution plan]
f.将解析结果存储到共享 SQL 区
g.将分布式语句[distributed statement]的部分或全部传递到包含相关数据的远程节点
3)描述查询结果
当查询结果的特性[characteristic]不确定时,语句处理需要经过描述[describe]步骤。例如,如果查询是由用户交互式地输入的,则需要经过描述步骤确定查询结果的特性(包括各结果字段的数据类型,长度,及名称)。
4)定义查询输出
在查询处理的定义步骤中,用户需要设定用于接收获取值的变量的位置,数据类型,及容量。这样的变量被称为定义变量[define variable]。在需要时 Oracle 能够自动执行数据类型转换。
5)绑定变量
在此阶段,Oracle 已经解释了 SQL 语句的含义,但还缺乏足够的信息运行此语句。Oracle 还需要语句中包含的变量的值。
6)语句并行化
Oracle 能够并行化地执行查询(SELECT,INSERT,UPDATE,MERGE,DELETE),还能够并行化地执行某些 DDL 操作,例如创建索引,通过子查询创建表,及分区操作等。并行执行使用多个进程执行 SQL 语句,以提高执行速度。
7)运行语句
语句处理进行到此步骤时,Oracle 已获得了足够的信息及资源,此时语句可以开始执行。如果语句为查询或 INSERT 语句,不会对已有数据进行修改,因此不必对任何数据行加锁。如果语句为 UPDATE 或 DELETE 语句,则所有受影响的数据行都将被加锁,直至事务提交了 COMMIT,ROLLBACK,或 SAVEPOINT 命令锁才能被释放,锁能够避免其他数据库用户使用这些数据行。锁机制用于确保数据一致性。
8)获取查询的数据行
在数据获取[fetch]步骤,数据行将被选择并排序(如果查询要求排序),每个获取操作取回结果集中的一条数据行,取回最后一行后获取步骤结束。
9)关闭游标
处理 SQL 语句的最后一个步骤是关闭游标。