zoukankan      html  css  js  c++  java
  • Oracle的优化器(Optimizer)

     泉源:网海拾贝




    本文的方针:
    1、说一说Oracle的Optimizer及其相干的一些常识。
    2、答复一下为什么偶然一个表的某个字段明显有索引,当查询拜访一些SQL的执行筹算时,创造确不走索引的标题成效。
    3、如果你对 FIRST_ROWS、 ALL_ROWS这两种形式有疑惑时也可以看一下这篇文章。

    最先吧:


    Oracle在执行一个SQL之前,首先要声明一下语句的执行筹算,然后再按执行筹算去执行。声明语句的执行筹算的工作是由优化器(Optimizer)来完成的。差异的情况,一条SQL可以有多种执行筹算,但在某且自点,必定只要一种执行筹算是最优的,破耗时候是最少的。置信你必定会用Pl/sql Developer、Toad等东西去看一个语句的执行筹算,不过你可以对Rule、Choose、First rows、All rows这几项有疑问,因为我目下当今也是多么的,事先我也疑惑为什么选了以上的差异的项,执行筹算就变了?

    1、优化器的优化要领

    Oracle的优化器共有两种的优化要领,即基于端正的优化要领(Rule-Based Optimization,简称为RBO)和基于代价的优化要领(Cost-Based Optimization,简称为CBO)。
    A、RBO要领:优化器在声明SQL语句时,所遵循的是Oracle外部预定的一些端正。比方我们罕见的,当一个where子句中的一列有索引时去走索引。
    B、CBO要领:依词义可知,它是看语句的代价(Cost)了,这里的代价次要指Cpu和内存。优化器在判别可否用这种要领时,次要参照的是表及索引的统计信息。统计信息给出表的大小 、有少行、每行的长度等信息。这些统计信息开初在库内是没有的,是你在做analyze后才呈现的,许多的时侯逾期统计信息会令优化器做出一个错误的执行筹算,因些我们应实时更新这些信息。在Oracle8及当前的版本,Oracle罗列荐用CBO的要领。

    我们要大白,不必定走索引便是优的 ,比方一个表只要两行数据,一次IO就可以完成全表的检索,而此时走索引时则需要两次IO,这时对这个表做全表扫描(full table scan)是最好的。

    2、优化器的优化形式(Optermizer Mode)

    优化形式包括Rule,Choose,First rows,All rows这四种要领,也便是我们以上所说起的。如下我解释一下:

    Rule:不用多说,即走基于端正的要领。

    Choolse:这是我们应不雅注的,默许的情况下Oracle用的便是这种要领。指的是当一个表或或索引有统计信息,则走CBO的要领,如果表或索引没统计信息,表又不是特别的小,并且响应的列有索引时,那么就走索引,走RBO的要领。

    First Rows:它与Choose要领是相通的,所差异的是当一个表有统计信息时,它将因此最快的要领前去盘查的最先的几行,从总体上增进了照应时候。

    All Rows:也便是我们所说的Cost的要领,当一个表有统计信息时,它将以最快的要领前去表的扫数的行,从总体上进步盘查的吞吐量。没有统计信息则走基于端正的要领。

    3、如何设定选用哪种优化形式

    a、Instance级别

    我们可以经过历程在init<SID>.ora文件中设定OPTIMIZER_MODE=RULE、OPTIMIZER_MODE=CHOOSE、OPTIMIZER_MODE=FIRST_ROWS、OPTIMIZER_MODE=ALL_ROWS去选用3所提的四种要领,如果你没设定OPTIMIZER_MODE参数则默许用的是Choose这种要领。

    B、Sessions级别

    经过历程SQL> ALTER SESSION SET OPTIMIZER_MODE=<Mode>;来设定。

    C、语句级别

    这些需要用到Hint,比方:
    SQL> SELECT /* RULE */ a.userid,
    2 b.name,
    3 b.depart_name
    4 FROM tf_f_yhda a,
    5 tf_f_depart b
    6 WHERE a.userid=b.userid;

    4、为什么偶然一个表的某个字段明显有索引,当查询拜访一些语的执行筹算确不走索引呢?如何办理呢 ?

    A、不走索引大体有以下几个启事
    ♀你在Instance级别所用的是all_rows的要领
    ♀你的表的统计信息(最可以的启事)
    ♀你的表很小,上文提到过的,Oracle的优化器以为不值得走索引。
    B、办理设施
    ♀可以点窜init<SID>.ora中的OPTIMIZER_MODE这个参数,把它改为Rule或Choose,重起数据库。也可以运用4中所提的Hint.
    ♀删除统计信息
    SQL>analyze table table_name delete statistics;
    ♀表小不走索引是对的,不用调的。

    5、别的相干

    A、如何看一个表或索引可否是统计信息

    SQL>SELECT * FROM user_tables
    2 WHERE table_name=<table_name>
    3 AND num_rows is not null;

    SQL>SELECT * FROM user_indexes
    2 WHERE table_name=<table_name>
    3 AND num_rows is not null;

    b、如果我们先用CBO的要领,我们应实时去更新表和索引的统计信息,以免生形不吻合实的执行筹算。

    SQL> ANALYZE TABLE table_name COMPUTE STATISTICS;
    SQL> ANALYZE INDEX index_name ESTIMATE STATISTICS;

    详细的ANALYZE语句请参照Oracle8i/9i 的refrence文档。




    版权声明: 原创作品,应许转载,转载时请务必以超链接要领标明文章 原始来由 、作者信息和本声明。否则将追查法律责任。

  • 相关阅读:
    《Programming WPF》翻译 第8章 1.动画基础
    一些被遗忘的设计模式
    《Programming WPF》翻译 第4章 数据绑定
    《Programming WPF》翻译 第3章 控件
    《Programming WPF》翻译 第5章 样式和控件模板
    《Programming WPF》翻译 第7章 绘图
    《Programming WPF》翻译 第9章 自定义控件
    《Programming WPF》翻译 第7章 绘图 (2)
    《Programming WPF》翻译 第8章 前言
    关于Debug和Release之本质区别
  • 原文地址:https://www.cnblogs.com/zgqjymx/p/1975860.html
Copyright © 2011-2022 走看看