博客转自:http://blog.csdn.net/zwl000906/article/details/8530347
sql语句的执行步骤:
1)语法分析,分析语句的语法是否符合规范,衡量语句中各表达式的意义。
2) 语义分析,检查语句中涉及的所有数据库对象是否存在,且用户有相应的权限。
3)视图转换,将涉及视图的查询语句转换为相应的对基表查询语句。
4)表达式转换, 将复杂的 SQL 表达式转换为较简单的等效连接表达式。
5)选择优化器,不同的优化器一般产生不同的“执行计划”
6)选择连接方式, ORACLE 有三种连接方式,对多表连接 ORACLE 可选择适当的连接方式。
7)选择连接顺序, 对多表连接 ORACLE 选择哪一对表先连接,选择这两表中哪个表做为源数据表。
8)选择数据的搜索路径,根据以上条件选择合适的数据搜索路径,如是选用全表搜索还是利用索引或是其他的方式。
9)运行“执行计划”
2、oracle 共享原理:
ORACLE将执行过的SQL语句存放在内存的共享池(shared buffer pool)中,可以被所有的数据库用户共享 当你执行一个SQL语句(有时被称为一个游标)时,如果它和之前的执行过的语句完全相同, ORACLE就能很快获得已经被解析的语句以及最好的 执行路径. 这个功能大大地提高了SQL的执行性能并节省了内存的使用
3、SQL Select语句完整的执行顺序:
1)、from子句组装来自不同数据源的数据;
2)、where子句基于指定的条件对记录行进行筛选;
3)、group by子句将数据划分为多个分组;
4)、使用聚集函数进行计算;
5)、使用having子句筛选分组;
6)、计算所有的表达式;
7)、使用order by对结果集进行排序。
4、多表连接查询时顺序:
例如:
select * from a inner join b on a.bid=b.id inner join c on b.cid=c.id where a.XXX='XXX'
1)、from a、b、c作为数据源
2)、通过where a.XXX='XXX' 筛选a表里的数据
3)、a表与b表依次对比,根据on条件,筛选符合条件的数据集
4)、将a、b两张表得到的结果集再和c中的记录依次对比,筛选符合条件的数据集
5)、完成
注意:
在多表关联查询时,哪两个表先结合查询,要通过优化器的分析,走CBO模式,一般将数据多的放在里面,数据少的放在外面。这里是假定排序是a、b、c。
--------------------------------------------------------------------------------------------------------------
SQL处理过程:
OPERATION | PURPOSE |
OPEN | Allocate memory for data structures. |
PARSE | check syntax,genetate parse tree,check privileges,and create execution plan.Allocate private SQL area.Allcote shared SQL area. |
DESCRIBE | Return the types and length of query select list columns.Only required for queries provided by an alllication at run time. |
DEFINE | Define program memory location,type,and size of variables for select list columns. |
BIND | Specify the memory location and value of bind variables. |
EXECUTE | Execute the statement using all of the information provided so far. |
FETCH | Fetch the results into the define values. |
CLOSE | Free up resources and deallocate memory. |
当一个Oracle实例接收一条sql后
1、Create a Cursor 创建游标
2、Parse the Statement 分析语句
3、Describe Results of a Query 描述查询的结果集
4、Define Output of a Query 定义查询的输出数据
5、Bind Any Variables 绑定变量
6、Parallelize the Statement 并行执行语句
7、Run the Statement 运行语句
8、Fetch Rows of a Query 取查询出来的行
9、Close the Cursor 关闭游标
解析(PARSE):
1.在共享池中查找SQL语句
2.检查语法
3.检查语义和相关的权限
4.合并(MERGE)视图定义和子查询
5.确定执行计划
绑定(BIND):
1.在语句中查找绑定变量
2.赋值(或重新赋值)
执行(EXECUTE):
1.应用执行计划
2.执行必要的I/O和排序操作
提取(FETCH):
1.从查询结果中返回记录
2.必要时进行排序
3.使用ARRAY FETCH机制
--------------------------------------------------------------------------------------------------------------
DML 语句的处理
每种类型的语句都需要如下阶段:
第1步: Create a Cursor 创建游标
第2步: Parse the Statement 分析语句
第5步: Bind Any Variables 绑定变量
第7步: Run the Statement 运行语句
第9步: Close the Cursor 关闭游标
如果使用了并行功能,还会包含下面这个阶段:
第6步: Parallelize the Statement 并行执行语句
第1步: 创建游标(Create a Cursor)
由程序接口调用创建一个游标(cursor)。任何SQL语句都会创建它,特别在运行DML语句时,都是自动创建游标的,不需要开发人员干预。多数应用中,游标的创建是自动的。然而,在预编译程序(pro*c)中游标的创建,可能是隐含的,也可能显式的创建。在存储过程中也是这样的。
第2步:分析语句(Parse the Statement)
在语法分析期间,SQL语句从用户进程传送到Oracle,SQL语句经语法分析后,SQL语句本身与分析的信息都被装入到共享SQL区。在该阶段中,可以解决许多类型的错误。
语法分析分别执行下列操作:
翻译SQL语句,验证它是合法的语句,即书写正确
实现数据字典的查找,以验证是否符合表和列的定义
在所要求的对象上获取语法分析锁,使得在语句的语法分析过程中不改变这些对象的定义
验证为存取所涉及的模式对象所需的权限是否满足
决定此语句最佳的执行计划
将它装入共享SQL区
对分布的语句来说,把语句的全部或部分路由到包含所涉及数据的远程节点
* 以上任何一步出错误,都将导致语句报错,中止执行。
第3步: 描述查询结果(Describe Results of a Query)
描述阶段只有在查询结果的各个列是未知时才需要;例如,当查询由用户交互地输入需要输出的列名。在这种情况要用描述阶段来决定查询结果的特征(数据类型,长度和名字)。
第4步: 定义查询的输出数据(Define Output of a Query)
在查询的定义阶段,你指定与查询出的列值对应的接收变量的位置、大小和数据类型,这样我们通过接收变量就可以得到查询结果。如果必要的话,Oracle会自动实现数据类型的转换。这是将接收变量的类型与对应的列类型相比较决定的。
第5步: 绑定变量(Bind Any Variables)
Oracle知道了SQL语句的意思,但仍没有足够的信息用于执行该语句。Oracle 需要得到在语句中列出的所有变量的值。在该例中,Oracle需要得到对department_id列进行限定的值。得到这个值的过程就叫绑定变量(binding variables)
此过程称之为将变量值捆绑进来。程序必须指出可以找到该数值的变量名(该变量被称为捆绑变量,变量名实质上是一个内存地址,相当于指针)。应用的最终用户可能并没有发觉他们正在指定捆绑变量,因为Oracle 的程序可能只是简单地指示他们输入新的值,其实这一切都在程序中自动做了。
因为你指定了变量名,在你再次执行之前无须重新捆绑变量。你可以改变绑定变量的值,而Oracle在每次执行时,仅仅使用内存地址来查找此值。
如果Oracle 需要实现自动数据类型转换的话(除非它们是隐含的或缺省的),你还必须对每个值指定数据类型和长度。关于这些信息可以参考oracle的相关文档,如Oracle Call Interface Programmer's Guide
第6步: 并行执行语句(Parallelize the Statement )
ORACLE 可以在SELECTs, INSERTs, UPDATEs, MERGEs, DELETEs语句中执行相应并行查询操作,对某些DDL操作,如创建索引、用子查询创建表、在分区表上的操作,可以执行并行操作。并行化可导致多个服务器进程(oracle server processes)为同一个SQL语句工作,使该SQL语句可以快速完成,但是会耗费更多的资源,所以除非很有必要,否则不要使用并行查询。
第7步: 执行语句(Run the Statement)
此时,Oracle拥有所有需要的信息与资源,可以真正运行SQL语句了。如果该语句为SELECT查询或INSERT语句,则不需要锁定任何行,因没有数据需要被改变。如果语句为UPDATE或DELETE语句,则该语句影响的所有行都被锁定,防止该用户提交或回滚之前,别的用户对这些数据进行修改。这保证了数据的一致性。
对于某些语句,你可以指定执行的次数,这称为批处理(array processing)。指定执行N次,则绑定变量与定义变量被定义为大小为N的数组的开始位置,这种方法可以减少网络开销,也是优化的技巧之一。
第8步: 取出查询的行(Fetch Rows of a Query)
在fetch阶段,行数据被取出来,每个后续的存取操作检索结果集中的下一行数据,直到最后一行被取出来。上面提到过,批量的fetch是优化的技巧之一。
第9步: 关闭游标(Close the Cursor)
SQL语句处理的最后一个阶段就是关闭游标。