`
caihorse
  • 浏览: 143800 次
  • 性别: 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; ``` 此语句表示使用Append模式将 `TABLE2` 中的所有数据插入到 `TABLE1` 中。 #### 三、使用场景及注意事项 - **适用场景:** - **批量数据导入:**...

    实验一安装和配置Oracle数据库与使用SQL.doc

    【实验一:安装和配置Oracle数据库与使用SQL*plus】 实验目标是让学生深入了解Oracle数据库的安装过程,掌握数据库的创建和配置,理解Oracle数据库的存储结构,熟悉参数文件的应用,并熟练使用SQL*plus命令行工具...

    oracle hint 用法汇总

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

    java代码oracle数据库批量插入

    sql.append("insert into ex_log(EX_LOG_ID, EX_LOG_DATE) values(?, ?)"); ``` 这里的`EX_LOG_ID`和`EX_LOG_DATE`是目标表`ex_log`中的列名,而`?`表示参数占位符,实际执行时将被具体的值替换。 #### 3. 加载...

    项目数据库优化

    INSERT /*+append*/ INTO wjg_test5 SELECT * FROM wjg_test4 t4 WHERE ROWNUM ; ``` 由于非车险定价系统中的表操作往往涉及重新构建,如使用`TRUNCATE`语句,因此`append` hint的使用不会影响数据布局。 **五...

    ORACLE 高效SQL分析2(具体问题)

    - **解析**:使用`/*+append*/`提示可以在执行大量插入操作时提高性能,因为它绕过了某些Oracle默认的检查和操作,例如一致性检查和回滚段使用。 - **优化建议**:当插入大量数据时,考虑使用`/*+append*/`提示,但...

    ORACLE配置 配置PPT

    - **SQL*Plus** 是Oracle提供的一种命令行工具,用户可以通过它直接与Oracle数据库交互,执行SQL语句和PL/SQL块。 - 在Windows环境下,可以通过命令行输入 `sqlplus username/password@database` 来登录,其中`...

    提高oracle大数据访问性能

    INSERT /*+ APPEND */ INTO table_name SELECT * FROM table_name1; ``` - **作用**:使用`APPEND`提示可以让Oracle直接向表末尾插入数据,从而避免了中间数据页的分裂操作,加快了插入速度。 - **适用场景**:...

    Python英语单词整理.pdf

    24. **append** / **clear** / **copy** / **count** / **insert** / **pop** / **remove** / **reverse** / **sort**:列表方法,用于操作列表元素。 25. **add** / **discard** / **difference** / **...

    Oracle数据库应用培训--使用SQL.zipPlus工具.pptx

    SQL*Plus是Oracle数据库管理员和开发人员的重要工具,它提供了丰富的功能,包括数据操作、数据库管理、对象描述以及SQL语句的快速编辑。通过熟练掌握SQL*Plus,用户可以高效地与Oracle数据库进行交互,提升工作效率...

    Oracle8i_9i数据库基础.txt

    综上所述,这份文档涵盖了 Oracle8i 数据库的基础知识,包括 SQL*PLUS 的使用、PL/SQL 的基础、表结构的管理、高级特性如视图、存储过程等,以及一些更深入的主题如序列和同义词的使用。这对于想要学习或加深对 ...

    用c语言设计工资管理

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

    将数据库数据到出为SQL语句

    sqlInserts.Append($"INSERT INTO yourTable ({reader.GetName(i)}) VALUES ('{escapedValue}');\n"); } sqlInserts.AppendLine("\n"); // 添加新行分隔 } ``` 4. **保存为TXT文件**: 使用`StreamWriter`类...

    日积月累-oracle笔记

    1. **直接路径插入**:使用`INSERT /*+APPEND*/`语句,可以将数据直接写入数据文件,绕过Oracle的标准缓冲区,提高加载速度。但是,这种方法不支持回滚,因此在事务性要求较高的场景下需谨慎使用。 2. **并行插入**...

    快速掌握Oracle数据库中的Copy命令

    Oracle数据库中的Copy命令是SQL*Plus提供的一种便捷的数据复制工具,尤其对于DBA来说,它在处理表间数据复制任务时具有较高的效率。Copy命令允许用户在同一个数据库的不同表之间,甚至不同服务器的数据库之间复制...

    Oracle9i数据库开发培训教材

    从给定的文件信息中,我们可以提炼出一系列关于Oracle9i数据库开发的关键知识点,这些知识点不仅涵盖了Oracle9i的基础操作,还深入到了SQL*PLUS和PL/SQL的使用技巧,对于初学者和有一定经验的数据库开发者来说都是...

Global site tag (gtag.js) - Google Analytics