下图显示了SQL在Oracle内部处理的一般阶段:解析、优化、产生行源和执行。数据库可能会忽略某些步骤,这取决于具体的语句。                                                                                                       
1,SQL解析
     SQL处理的第一阶段就是SQL解析。当应用程序发出SQL语句时,该应用程序向数据库发出一个解析调用,以准备执行该语句,解析调用会打开或创建一个游标,它是一个对特定于会话的私有SQL区的句柄,其中包含了已分析的SQL语句和其他处理信息。游标和私有SQL区位于PGA中。
     解析调用期间,数据库会执行以下检查:
          ● 语法检查     
          ● 语义检查       --对象和列是否存在
          ● 共享池检查
     数据库执行共享池检查,以确定时候可以跳过占用大量资源的语句处理步骤。为此,数据库使用一种哈希算法为每个SQL语句生成一个哈希值。语句的哈希值即是在V$SQL.SQL_ID中显示的SQL_ID(参考笔记:区分4个与sql相关的字段:hash_value、sql_hash_value、plan_hash_value 和 sql_id),当用户提交一个SQL语句时,数据库搜索共享SQL区,以查看是否存在一个现成的已分析的语句具有相同的哈希值。SQL语句的哈希值有别于下列值:
     ● 该语句的内存地址值(V$sql的address字段值)
     ● 该语句执行计划的哈希值(V$SQL_PLAN视图的plan_hash_value字段值)
 
     基于所提交语句的类型和哈希检查的结果,解析操作分为以下类别:
     ● 硬解析
        如果数据库不能重用现有代码,则它必须生成应用程序代码的一个新的可执行版本,次操作称为一个硬解析,或库缓存未命中。数据库对DDL始终执行硬解析。
        在硬解析期间,数据库多次访问库缓存和数据字典缓存以检查数据字典。当数据库访问这些区域时,它在所需对象上使用一个叫做闩锁的串行化设备,以便它们的定义不糊被更改。闩锁的争用会增加语句的执行时间,并降低并发性。
     ● 软解析
         任何不适硬解析的解析都是软解析。如果提交的语句与在共享式中某个可重用SQL语句相同,则数据库将重用该现有代码。重用代码也称为库缓存命中
         一般的,软解析比硬解析更可取,因为数据库可以跳过优化和行源生成步骤,而直接进入到直行阶段。下图是在专用服务器体系结构中,一个update语句的共享池检查的简化表示。
           
     (看来,SQL文本的哈希值是在PGA中产生的)。
          如果检查到共享库中有一个语句具有相同的哈希值,则数据库在执行语义和环境检查(工作区大小或优化器设置等),当然还有语句本身的书写(大小写,空格,注释等)。
     详情可参见笔记:《Oracle性能调优之硬解析与软解析》
 
2,SQL优化
     查询优化是选择执行SQL语句的最有效手段的过程。数据库对查询的优化基于对正在访问的实际数据收集的统计信息。优化器使用行数、数据集大小 和 其他因素来生成各种可能的执行计划,并为每个计划分配一个成本值。数据库会使用具有最低成本的计划。
     数据库对每个唯一的DML语句必须至少执行一次硬解析,并在硬解析期间执行优化。DDL永远不会被优化,除非他包括需要优化的DML组件,如子查询。
 
3,SQL行源生成
     行源生成器是一种软件,它从优化器接受经过优化的执行计划,并生成一个称为查询计划的迭代计划,一共数据库的其余部分使用。查询计划采用组合多个步骤的形式,每一步返回一个行集。该集合中的行可以在下一步被使用,火灾最后一步返回给发出SQL语句的应用程序。
     行源就是执行计划中的某一步多返回的行集,且带有能够迭代该行集的控制结构,行源可以是表、视图、或连接操作或分组操作的结果。
     行源生成器产生一个行源树,它是一个行源的集合。(就是我们看到的执行计划)
 
4,SQL执行
     在执行期间,SQL引擎执行行源生成器所产生的数中的每个行源。这一步是在DML处理中唯一的强制性步骤。在执行计划中,我们经常看到就是的一个执行树,显示了行源从一部流向另一步。通常,执行步骤的顺序与几乎是顺序相反,所以我们应该从底向上来阅读计划。在operation列中的初始空格表示层次结构关系。例如,如果一个操作的名称前面有两个空格,则此操作是前面有一个空格的操作的子操作。前面有一个空格的操作是select语句本身的子操作。
 
参考:http://docs.oracle.com/cd/E11882_01/server.112/e40540/sqllangu.htm#CNCPT216

最新文章

  1. Eclipse注释模板设置详解
  2. MIT 6.828 JOS学习笔记17. Lab 3.1 Part A User Environments
  3. JSON字符串与JSON对象的区别
  4. MYSQL存储过程:批量更新数据
  5. hive处理hbase数据
  6. 《Unix/Linux日志分析与流量监控》书稿完成
  7. NSURLSession 请求
  8. 《SDN核心技术剖析和实战指南》2.1交换机核心技术小结
  9. SUSAN检测算子
  10. C#入门经典(2-重置窗体布局,界面介绍,错误列表)
  11. magento1.x 运行在 php7 优惠券的问题
  12. input表单的type属性详解,不同type不同属性之间区别
  13. ipv4与ipv6的区别
  14. 一、TensorFlow的简介和安装和一些基本概念
  15. es集群数据库~原理细节
  16. [转]Ubuntu 常用解压与压缩命令
  17. 【2017-02-28】C# 冒泡排序
  18. 基于python3在nose测试框架的基础上添加测试数据驱动工具
  19. 消息队列库——ZeroMQ
  20. 20165233 2017-2018-2 《Java程序设计》第八周学习总结

热门文章

  1. margin与padding的区别是什么?
  2. 【leetcode】1131. Maximum of Absolute Value Expression
  3. HTTP content-type及POST提交数据方式
  4. idea上把项目推送到GitHub上
  5. 跳转控制语句return
  6. 解决报错:The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized
  7. Oracle--SQL程序优化案例一
  8. 13 November
  9. python的filter,reduce,map
  10. 阶段1 语言基础+高级_1-3-Java语言高级_1-常用API_1_第5节 String类_10_练习:统计输入的字符串中