Oracle对SQL语句处理过程

来源:互联网 发布:php返回数据格式 编辑:程序博客网 时间:2024/06/10 22:44

  本文参考《Oracle性能优化求生指南》


    Oracle对SQL语句处理过程如下图所示:


     通过上图可知,一个SQL语句处理的过程如下:

      1)创建游标。

               游标是内存中的一块区域用于保存当前的SQL语句的定义信息。

      2)检查缓存。

              每提交一个SQL语句的执行请求,Oracle都会向共享池(shared pool)的SQL Area中检索是否存在该SQL的执行计划,

       如果有就不需要重新解析SQL。

      3)解析SQL语句。

              解析SQL语句设计检查SQL语句的语法、对象引用,以及调用Oracle优化器来确定并生成执行计划。

              解析的过程如下:

                 ① 检查SQl语句的语法是否有效,也就是这条SQL语句是否遵循SQL语言的规则,以及所有的关键字与操作符是否都有效

                      并被正确使用。

                 ② 检查SQL语句在语义上是否有效。就是SQL语句引用的所有数据库对象(即表和字段)否都是有效的

                 ③ 检查用户是否有对所有相关对象执行给定操作的安全权限。

                 ④ 确定SQL语句的执行计划。这一步是有Oracle优化器(optimizer)来完成的。

             注意:解析SQL语句是发生在为绑定变量赋值之前,所以如果一个SQL语句有绑定变量,在关联绑定变量之前该

                 SQL的执行计划已经生成,后面即便绑定变量被赋予不同的值执行,它们的执行计划是相同的。

      4)关联绑定变量。

               执行SQL语句前,所有绑定变量(表示需要有调用程序提供响应值的占位符)的值都必须黏附到这条SQL语句上。

               为什么要使用绑定变量呢?

               例如,插入编号为100003的学生姓名,语句如下:

SQL> select name from t_student where gid = 100003;NAME--------------------------------------------------------------------------------CHENZHEN

           但是如果我们想查询编号为100004的学生姓名,就需要生成新的执行计划,因为SQL语句检索缓存时,要求SQL语句必须
全一致才可能在共享池找到匹配执行计划。怎么才能让上面SQL语句在gid值不同情况使用相同的执行计划,即后续重复执
       行该查询SQL时,能从缓存查询执行计划?答案是:变量绑定,即将gid的值绑定在一个变量中,如下代码:

SQL> variable id number;SQL> exec :id := 100003;PL/SQL procedure successfully completedid---------100003SQL> select name from t_student where gid = :id;NAME--------------------------------------------------------------------------------CHENZHENid---------100003

               或

declare   v_name t_student.name%type;   p_id number;begin  p_id := 100003;  execute immediate ' select name from t_student where gid = :1' into v_name using p_id; --动态SQL为查询语句  dbms_output.put_line('编号为'||p_id||'的学生姓名是'||v_name);end;

                使用绑定变量的原因:

                 ① 如果绑定变量值发生变化,重新执行这条SQL语句时,它可以在共享池中找到一条相同SQL的执行计划,不需要重

                     新解析这条SQL语句。

                 ② 如果其他会话也执行同一条SQL语句,它可以在共享池中找到一条相同SQL的执行计划,不需要重新解析这条SQL

                    语句。

      5)执行SQL语句。

                    如果这条SQL语句不是查询语句,它的执行过程将包含DML语句或者DDL语句的执行。如果这条SQL语句是查询语句,

             执行并将为语句的数据提取做准备。

      6)提取游标

                    游标的提取是Oracle从磁盘或高速缓存中提取数据,并将提取的数据从SQL引擎返回到PL SQL引擎。为了提高查询的

             性能,可以一次提取多条数据,即批量提取,这样就可以减少从SQL引擎将结果返回到PL SQL引擎的次数。关于

             批量提取请参考《Oracle的bulk collect使用》

      7)关闭游标

                      释放分配的内存并销毁游标。

0 0
原创粉丝点击