【ORACLE数据库中的SQL优化原理与应用】 c#面试题

  摘 要:Oracle数据库系统时时刻刻都要处理用户提交的SQL语句,把结果返回给用户。因此数据库的性能直接表现在SQL的运行性能上,理解SQL执行过程的细节,包括资源的分配、算法的生成对于调整非常有意义。探讨了Oracle数据库中的SQL优化原理与应用。
  �
  关键词:Oracle数据库;SQL优化;原理�
  中图分类号:TP391 文献标识码:A 文章编号:1672-7800(2012)003-0164-02��
  �
  作者简介:刘笑尘(1990-),女,河北沧州人,重庆大学软件学院本科生,研究方向为数据库技术。
  
  
  0 引言�
  Oracle数据库系统性能调整是一个综合性的问题,要根据环境(包括服务器环境、操作系统、网络)和应用类型来确定。在进行Oracle数据库性能调整时,要根据系统在运行过程中产生的日志记录来进行(大部分信息保存在admin目录下的后台进程跟踪文件中)。系统性能很大程度上取决于SGA(系统全局区)的配置。系统全局区是一个分配给Oracle例程的内存段。主要包括数据库高速缓冲区(Database buffer cache)、重做日志缓冲区(Redo log buffer)、共享池(Shared POOl)、数据字典缓冲区(Data dictionary cache)以及其它各方面的信息。用户有两种方式连接到Oracle:共享连接和专有连接。在实际工作中,专有连接是最常用的方式,因此本文将以专有模式为重点进行介绍。�
  1 SQL语句的执行过程�
  (1)Synatic:语法分析。这一步检查SQL语句的语法是否正确,有没有拼写错误,比如把Select写成Selet。�
  (2)Semantic:语义分析。这一步检查要查询的对象是否存在,以及用户是否具有操作该对象的权利。�
  (3)Parent Cursor。在Library Cache中检查语句的Cursor是否存在,如果存在可以重用的Cursor(包括Parent Cursor和Child Cursor),则把PGA的Private SQL Area和其做关联,然后直接跳到第(8)步。这种解析也叫做软解析(SoftParse)。如果没有就申请一个Parent Cursor,Parent Cursor就是用来保存SQL语句的,然后继续第(4)步。�
  (4)View Merge。如果用户的语句中用到了视图(View),把视图语句合并到用户语句中。�
  (5)Statement Transformation。把Complex SQL转换成Simple SQL,比如展开子查询(这部分内容在后面会有专门介绍)。某些资料也把(4)和(5)这两步操作叫做逻辑优化(Logical Optimization)。�
  (6)Optimization。确定最佳的访问路径。如果是RBO,根据一些预定义的规则来决定访问路径;如果是CBO,则根据对象的统计信息确定访问路径。SQL语句是一种典型的“声明式语言”,也就是说SQL语句只是描述“做什么”,但并不规定“如何做”,“如何做”是优化器引擎的工作。SQL语言是关系理论在计算机世界中的表达方式,关系理论有着严密的数学基础,同一个关系表达式可以用不同的计算方式获得相同结果。类似于数学中的运算转换,比如(3+2)×4,即可以通过(3+2)×4=5×4=20这种顺序计算,也可以通过(3+2)×4=3×4+2×4=20这种方式计算。具体采用哪种算法,完全取决于CPU指令设计。对应到数据库引擎,Oracle优化器会尝试分析所有可能的数据访问方式,对每种方法计算出其代价(Cost),最终选择代价最小的访问方式。�
  (7)QEP Generation:生成执行计划(Query Execution Plan)。也就是产生Child Cursor。执行计划会保存在Child Cursor中,并和Parent Cursor相关联。在Child Cursor中保存的是执行计划和执行环境信息(比如优化器模式)。�
  和软解析(Soft Parse)相对应,如果一个语句完整地经历了第(1)-(7)步,这个解析过程叫做硬解析(Hard Parse)。�
  (8)QEP Execution:执行语句,生成结果。�
  步骤(1)-(7)统称为解析(Parsing)。解析的最终结果就是生成执行计划。每个SQL语句和它的执行计划都被保存在Library Cache中,而Oracle对Library Cache的访问也就基于Hash方式。每个SQL语句根据相同的Hash算法,得到一个Hash值,然后利用这个Hash值去检索Library Cache。�
  2 SQL查询性能优化原理�
  2.1 优化排序操作�
  2.1.1 对经常进行排序和连接操作的字段建立索引�
  建立索引后,当服务器向这些字段发出排序请求时,将直接引用索引而不进行排序操作;为了使用基于成本的优化器,必须经常运行 analyze 命令,以增加数据库中的对象统计信息(object statistics)的准确性。有3种重建索引的方法:①先删除再重建。这种方法耗费最多的资源,是早期版本的唯一方法;②ALTER INDEX … REBUILD。这种方法高效快速,但需要额外的磁盘空间。用这种方法可以指定许多选项如 ONLINE(在线重建可减少锁争用),TABLESPACE( 移动段到其它表空间),COMPUTE STATISTICS(统计),PARALLEL(并行),NOLOG-GING(尽可能少地产生日志);③ALTER INDEX … COALESCE。这种方法快速,无需额外空间,锁争用也少,缺点是选项少。�
  2.1.2 书写 SQL 语句要尽可能使用索引�
  创建索引后,如果 SQL 语句书写不当,优化器生成的执行计划也不会包含索引,应该避免下列情况:�
  
  2.2 减少排序�
  2.2.1 用 Union All 代替 Union�
  Union 在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果。实际大部分应用中是不会产生重复的记录,最常见的是过程表与历史表Union,如:�
  SELCT * FROM CW_INCOME UNION�
  SELECT * FROM CW_REALINCOM�
  这个 SQL 在运行时先取出两个表的结果,再用排序空间进行排序删除重复的记录,最后返回结果集,如果表数据量大的话可能会导致用磁盘进行排序。�
  2.2.2 使用Where代替Having�
  避免使用Having子句,Having只会在检索出所有记录之后才对结果集进行过滤。这个处理需要排序、总计等操作。 如果能通过Where子句限制记录的数目,那就能减少这方面的开销。�
  3 Oracle数据库中的SQL优化应用�
  SQL优化的实质就是在结果正确的前提下,充分利用索引,减少表扫描的I/O次数,选择最有效的执行计划来执行SQL语句的过程。下面的查询优化实例以EMP和DEPT表为查询表,其中emp表有1 204行记录,dept有604行记录。�
  (1) select子句中避免使用*。Oracle在解析的过程中,通过查询数据字典将*依次转换成所有的列名,这将消耗更多的时间,降低查询速度。优化例1如表1所示。�
  
  (3)用Truncate替代Delete。Truncate Table命令快速删除数据表中的所有记录,但保留数据表结构。这种快速删除与Delete删除全部数据表记录不同,Delete命令将删除的数据将存储在系统回滚段中,需要的时候,数据可以回滚恢复,而Truncate命令删除的数据是不可以恢复的。�
  (4)用Union替换or(适用于索引列)。在Where子句中or连接多个索引列,用Union替换Where子句中的or,可以显著提高查询效率。对索引列使用or将造成全表扫描,如果用or连接的列没有被索引,查询效率不会提高。Union在进行表连接后,对所产生的结果集进行排序运算,筛选掉重复的记录再返回结果。而Union all操作只是简单的将两个结果合并后就返回,在结果重复度不高的情况下采用Union all操作符替代Union,也可以提高查询速度。如表2所示。
  
  4 结束语�
   在数据库应用开发过程中,优化设计可提高数据库性能,特别是大型数据库,优化过程更为重要 当然数据库性能优化是一个复杂过程,本文只是对数据库中 SQL 的优化原理进行了分析并提供了一些优化建议,供实际应用时参考。
  
  
  参考文献:�
  \[1\] 唐远新,曲卫平,李晓峰.Oracle数据库实用教程\[M\].北京:中国水利水电出版社,2009.�
  \[2\] 杨厚云,龚汉明,武装.Oracle 数据库性能优化方案\[M\].北京:北京机械工业学院学报, 2006(4).�
  \[3\] 戴小平.Oracle 9i 数据库性能调整与优化\[M\].安徽工业大学学报, 2006(3).�
  \[4\] 杜庆峰,张卫山.Oracle 的中大型应用系统性能优化分析\[J\].计算机工程, 2005(14).�
  (责任编辑:杜能钢)�

推荐访问:数据库中 原理 优化 ORACLE