`
caihorse
  • 浏览: 140699 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Oracle数据库的配置和SQL语句的优化 /*+ rule */ & INSERT/*+append*/INTO

阅读更多

Oracle数据库的配置和SQL语句的优化 。

  INSERT/*+append*/INTO t_servicexx(serviceid,clientid,prod_id,serviceno,addrid,
                                      connectno,fgsid,gl_serviceid,up_serviceid,servlev,
                                      dialacctname,ibss_id,gl_serviceid_num,phone_nbr,orgid)

2         Oracle数据库的配置
2.1 影响SQL效率的关键因素和配置:
       Oracle数据库上的设置对其性能的影响很大,如Shared Pool Size、Buffer Cache Size、SGA Structures、Database I/O Configuration、Rollback Segments等等,这些是DBA(数据库管理员)要根据实际状况需性能调整的部分。
 
       我们在平时工作中用到大量的View,View中SQL的写法对效率的影响很大,首先有必要了解一条SQL语句是如何被执行的。当SQL语句进入Oracle的缓存后,在该语句准备执行之前,DBMS将执行下列步骤:
      ⑴  SQL语法检查:检查SQL语句拼写是否正确和词序。
      ⑵ SQL语义分析:核实所有的与数据字典不一致的表和列的名字。
      ⑶ 生成执行计划:使用优化规则和数据字典中的统计表来决定最佳执行计划。
      ⑷ 建立可执行的二进制代码:基于执行计划,Oracle生成二进制执行代码。
      ⑸ 抓取并返回需要的数据。
      其中第三步生成执行计划非常关键,所谓执行计划,就是对一个查询任务,做出一份怎样去完成任务的详细方案。对于查询而言,我们提交的SQL仅仅是描述出了我们的目的,但Oracle内部怎么去得到这些数据,是由数据库DBMS来决定的。
所以执行计划产生的好坏直接影响SQL运行的效能。
 
      在不同的情况下,同一条SQL可能有多种执行计划。但理论上在某一时点,一定只有一种执行计划是最优的、花费时间是最少的。执行计划的工作是由优化器(Optimizer)来完成的,我们先要了解一下Oracle的优化器:
 
      ORACLE优化器的优化方式有两大类,即基于规则的优化方式(Rule-Based Optimization,简称为RBO)和基于代价的优化方式(Cost-Based Optimization,简称为CBO)。
      ⑴ RBO方式:优化器在分析SQL语句时,根据数据库中表和索引等定义信息,遵循的是Oracle内部预定的一些规则。比如我们常见的:当一个where子句中的一列有索引时去走索引而不走全表扫描。
      ⑵ CBO方式:依词义可知,它是看语句的代价(Cost)了。基于代价的查询,数据库根据搜集的表和索引的数据的统计信息(统计信息通过analyze 命令或者使用dbms_stats包来搜集)综合来决定选取一个数据库认为最优的执行计划。统计信息给出表的大小 、有多少行、每行的长度等信息。
      注意:这些统计信息起初在库内是没有的,是根据 analyze 命令或者dbms_stats包来定期搜集后才出现的,所以很多的时候过期统计信息会令优化器做出一个错误的执行计划,因此我们应及时更新这些信息。为了使用基于成本的优化器(CBO) , 你必须经常运行analyze或dbms_stats命令,以增加数据库中的对象统计信息(object statistics)的准确性。
在Oracle8及以后的版本,Oracle强列推荐用CBO的方式。
 
       优化模式包括Rule,Choose,First rows,All rows这四种方式,先解释一下:
       ⑴ Rule:即走基于规则的方式。
       ⑵ First_Rows:基于成本的方式。指执行计划采用最少资源尽快的返回部分结果给客户端,它将是以最快的方式返回查询的最先的几行,从总体上减少了响应时间,对于排序分页页显示这种查询尤其适用。
       ⑶ All_Rows:基于成本的方式。当一个表有统计信息时,它将以最快的方式返回表的所有的行,从总体上提高查询的吞吐量。没有统计信息则走基于规则的方式。
       ⑷ Choose:这是我们应关注的,默认的情况下Oracle用的便是这种方式。指的是当一个表或索引有统计信息(指运行过analyze 命令或者使用过dbms_stats包来搜集),则走CBO的方式 (在CHOOSE模式下ORACLE采用的是 FIRST_ROWS);如果表或索引没统计信息,那么走RBO的方式。
       注:Oracle ERP 11i之前的版本,默认用RULE;Oracle ERP 11i之后的版本,默认用CHOOSE。
 
       ⑴ Instance级别:我们可以通过在<init>.ora文件中设定OPTIMIZER_MODE=<Mode>去选用。
       ⑵ Sessions级别:通过SQL> ALTER SESSION SET OPTIMIZER_MODE=<Mode>;来设定。  
        ⑶ 语句级别,这些需要用到Hint,比如:
SELECT /*+ rule */ ordh.order_number,ordl.ordered_item
  FROM apps.oe_order_headers_all ordh, apps.oe_order_lines_all ordl
 WHERE ordh.header_id = ordl.header_id;
 
       对CBO模式,对象统计信息至关重要。我们可以用如下SQL查询到:
SELECT table_name,num_rows, blocks, empty_blocks AS empty, avg_space, chain_cnt, avg_row_len
  FROM dba_tables
 WHERE owner = 'ONT' AND table_name = 'OE_ORDER_LINES_ALL'
TABLE_NAME
NUM_ROWS
BLOCKS
EMPTY
AVG_SPACE
CHAIN_CNT
AVG_ROW_LEN
OE_ORDER_LINES_ALL
4344
505
5
0
0
441
可以看到数据字典中统计到的该表有5344笔记录
      Oracle ERP11i用的optimizer_mode是choose,且Oracle强烈建议要定期运行FND_STATS。
       Oracle DB中常用的Gather有以下一些,DBA也可以直接在Database级别上定期Run这些Function,以便能让Oracle统计到最新的数据库状况:
       dbms_stats.gather_database_stats();
       dbms_stats.gather_schema_stats();
       dbms_stats.gather_table_stats();
       dbms_stats.gather_index_stats();
2.5      跟踪 SQL实际运行的Cost
       执行计划是Oracle根据一些统计信息去“估计”出各个步骤所耗的Cost,与实际的执行过程所耗Cost不见得一样。实际执行过程耗的CPU、Disk IO等资源的数量可以通过sql_trace统计出来。所以Tuning SQL不仅要看“执行计划”,有时还必须结合trace的Log去分析。
3         SQL语句的优化:
          SQL语句的优化是需要不断尝试的,在此把自己的经验分享一二。
3.1      绝大多数情况下not exists比not in 效率高
3.2      UNION ALL效率比UNION高很多
3.3      一些很耗资源的SQL操作,在不必要的情况下不要使用
          Select *,Order by,Group by,Distinct, UNION, MINUS,INTERSECT 操作是相当耗时的,在View中能不使用就不要使用。 通常, 带有UNION, MINUS , INTERSECT的SQL语句都可以用其它方式重写。
          尽量在 SELECT 子句里面用联接查询,少用子查询。因为子查询所得到的子Table的数据量等信息是Oracle无法事前统计出来的,所以优化器也很难得出一个优化过的执行计划。
          如果Table上有索引,则系统访问带索引的Field时,可通过访问索引中的栏位来快速获得相对应记录的ROWID,而通常情况下,使用索引比全表扫描要块几倍乃至几千倍。
           Oracle ERP中几乎所有的Table都设有索引,尽量以索引中的栏位做 join,避免用我们认为值是唯一的栏位去串
3.6      在View中尽量不要使用 Package/function 来得到栏位值,
在view中尽量不要引用function,否则会增加一定的通讯开销。简单的判断尽量用decode,nvl,case when等实现。
3.7      通过ROWID访问表 
  ORACLE 采用两种访问表中记录的方式:
    ⑴ 全表扫描 
        全表扫描就是顺序地访问表中每条记录. ORACLE采用一次读入多个数据块(database block)的方式优化全表扫描.
    ⑵ 通过ROWID访问表
如果可以,强烈采用基于ROWID的访问方式情况以提高访问表的效率。ROWID包含了表中记录的物理位置信息,ORACLE采用索引实现了数据和存放数据的物理位置之间的联系, 通常索引提供了快速访问ROWID的方法,因此那些基于索引列的查询就可以得到性能上的提高。
 
3.8      必要时可在Oracle原表上加索引
3.9      合理排列WHERE子句中的连接顺序.
        ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,那些可以过滤掉最大数量记录的条件最好写在WHERE子句的末尾。虽然对简单SQL,Oracle优化器自动会去调整顺序,但还是建议将能过滤掉最多记录的Where条件放在最后。
 
3.10  用Where子句替换HAVING子句
        避免使用HAVING子句, HAVING 只会在检索出所有记录之后才对结果集进行过滤。 这个处理需要排序,总计等操作。 如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销。
3.11 关于使用索引(Index)的一些注意点
         而通常情况下,使用索引比全表扫描要块几倍至几千倍。某些情况下SELECT 语句中的WHERE子句用到索引列,但生成的执行计划却不使用索引。这里有一些例子.
  1.          ‘!=’,NOT操作将不使用索引.
  2.          ‘||’是字符连接函数. 就象其它函数那样, 停用了索引.
  3.           相同的索引列不能互相比较,这将会启用全表扫描.
  4.          避免在索引列上使用计算.
3.12 识别 “低效运行”的SQL语句
         用下列语句找出与我们客制有关的低效SQL:
SELECT EXECUTIONS , DISK_READS, BUFFER_GETS,ROUND((BUFFER_GETS-DISK_READS)/BUFFER_GETS,2) Hit_radio, ROUND(DISK_READS/EXECUTIONS,2) Reads_per_run,SQL_TEXT
FROM   V$SQLAREA
WHERE  sql_text like '%XX%' AND EXECUTIONS>0 AND BUFFER_GETS > 0  AND (BUFFER_GETS-DISK_READS)/BUFFER_GETS < 0.8
ORDER BY 4 DESC;
分享到:
评论
1 楼 yarkingJ 2011-08-19  
不错,谢谢分享!

相关推荐

    /* append*/ oracle append 知识点

    INSERT /*append */ INTO TABLE1 AS SELECT * FROM TABLE2;

    oracle hint 用法汇总

    里面是ORACLE SQL 优化时会用到的hint示例汇总。总共有30个hint。 全部都是hint说明及示例。下面展示一个示例。 /*+noappend*/ 通过在插入语句生存期内停止...insert /*+noappend*/ into test1 select * from test4 ;

    用c语言设计工资管理

    void insert(); /*插入*/ void append(); /*追加*/ void copy(); /*复制文件*/ void sort(); /*排序*/ void index(); /*索引*/ void total(); /*分类合计*/ void list(); /*显示所有数据*/ void print(SALARY *p); /...

    oracle DBA_TAB_MODIFICATIONS 刷新

    3、对于/*+ append */ 插入的操作,表同样记录 4、表一旦被分析,信息就会从视图消失。 5、dml操作表记录准确无误,truncate 操作:TRUNCATED 字段为: YES 6、隐含参数:"_dml_monitoring_enabled" 值为false 时,不...

    用C编写班级成绩管理系统

    这是一个无参函数,里面只有两个语句,它的作用是使链表初始化,使head的值为NULL和一个清屏语句。比如:没有这个函数的话,在你没有输入任何数据的情况下,去执行显示功能的时候会显示一些乱码! 输入记录函数 ...

    Oracle 10gR2压缩(Compress)技术

    4.3 insert /*+ append */压缩 6 4.4 alter table …move compress压缩 7 4.5 alter table … move partition … compress 8 5、分区表的压缩测试 8 5.1 分区表创建 8 5.2 分区表压缩属性查看 8 5.3 分区表压缩属性...

    C语言课程设计--职工管理系统.

    本系统是一个单纯的课程设计,很简单的...void append() void modify() void show() void insert() void delet() void search() void sort() void total() void message() char menu() /*菜单选择函数*/ void jieshu()

    ORACLE SQL-UPDATE、DELETE、INSERT优化和使用技巧分享

    UPDATE 1、先备份数据(安全、提高性能)。2、分批更新,小批量提交,防止锁表。3、如果被更新的自动有索引,更新的数据量很大,先取消索引,再重新创建。...)2、使用/*+ append */ 暗示。3、绑定变

    chatRoom 聊天室

    chatRoom.zip 聊天室聊天室服务端 package chatroom; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader;...import java.io.PrintStream;... * 客户端窗口...

    MD5Code加密技术

    // /* Append length (before padding) */ md5Update(bits, 8); // /* Store state in digest */ Encode(digest, state, 16); } /* * md5Memcpy是一个内部使用的byte数组的块拷贝函数,从input的inpos开始把...

    最全的oracle常用命令大全.txt

    ORACLE常用命令 一、ORACLE的启动和关闭 1、在单机环境下 要想启动或关闭ORACLE系统必须首先切换到ORACLE用户,如下 su - oracle a、启动ORACLE系统 oracle&gt;svrmgrl SVRMGR&gt;connect internal SVRMGR&gt;startup ...

    MD5加密类详细写法

    FF,GG,HH和II将调用F,G,H,I进行近一步变换 FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. Rotation is separate from addition to prevent recomputation. */ private long FF(long a, ...

    SQL语句拼装工具V2

    写java程序时用来拼装sql语句时使用的小工具,在.net 4.0环境下运行。 跟前一版本比较,增加了前缀和空格位置的自定义,并增加了一个配置文件,保存自定义项 例如将 select a, b, c from abc where a like('3') ...

    jsp分页插件--PageBean(java源码)

    * PageControl, 分页控制, 可以判断总页数和是否有上下页. * * 2008-07-22 加入输出上下分页HTML代码功能 * * @author HX * @version 1.1 2008-9-22 */ public class PageBean { /** 每页显示记录数 */ ...

    ZIP 压缩 解压缩 源码

    const char* zipfilename, bool append = false&#41;; bool CloseZipFile&#40;const char* global_comment = NULL&#41;; private: void* zipfile_;/* = NULL */ }; /* */ #define MAX_COMMENT (255) /* tm_unz ...

    mysql+java课程设计学生管理系统

    String sql="insert into t_book values(null,?,?,?,?,?,?)"; PreparedStatement pstmt=con.prepareStatement(sql); pstmt.setString(1, book.getBookName()); pstmt.setString(2, book.getAuthor()); pstmt....

    SQL语句拼装工具

    写java程序时用来拼装sql语句时使用的小工具,在.net 4.0环境下运行。例如将 select a, b, c from abc where a like('3') 转换为: sql.append("select "); sql.append(" a, "); sql.append(" b, "); sql.append...

    数据库有关SQL实验学习

    创建触发器的语法为: CREATE TRIGGER 触发器&gt; ON &lt;表名&gt; [WITH ENCRYPTION] FOR {[DELETE][,][INSERT][,][UPDATE]} [WITH APPEND] [NOT FOR REPLICATION] AS &lt;SQL 语句组&gt; 其中:

    sql访问数据库工具类--SqlUtils(java源码)

    buffer.append("SELECT ").append(this.getBeanShortName()).append( " FROM ").append(this.getBeanName()).append(" ").append( this.getBeanShortName()).append(" ").append(buildWhereStr()) ....

    jdbc连接代码

    // Statement作用是向数据库中发送sql语句,并告诉数据库执行sql语句,还要让数据库返回执行的结果 stmt = conn.createStatement(); // 向数据库中发送sql,并执行,获取执行结果 rs = stmt....

Global site tag (gtag.js) - Google Analytics