nested loops/hash join

nested loops适用于一大一小表。其中内表是小表,每取一次值,然后与外表匹配。
若内表复杂度为n,外表复杂度为m,则整体为O(n*m)
hash join 适用于大表关联。若内表复杂度为n,外表复杂度为m,则整体为O(n+m)

索引:
特殊情况下,索引扫描反而不如全表扫描效率高。如索引字段值90%为同一值时,全表扫描效率更高。当过滤字段加上后,选取数据量较少时,索引能够大大发挥优势。即筛选出来行的占表总行数比很小

手动执行分析:
SQL> exec dbms_stats.gather_table_stats(user,'t1',cascade=>true);

PL/SQL procedure successfully completed.

SQL> exec dbms_stats.gather_table_stats(user,'t2',cascade=>true);

PL/SQL procedure successfully completed.

谓词:
    Access: 表示这个谓词条件的值将会影响数据的访问路劲(全表扫描还是索引)。
    Filter:表示谓词条件的值不会影响数据的访问路劲,只起过滤的作用。
在下文中,select * from t2, t1 where t2.id=t1.id and t2.id=2;
id=2表现为access,因为它决定了访问路径。

INDEX RANGE SCAN对应的是access
而TABLE ACCESS FULL对应的是FILTER(有待确定)


动态分析:
dynamic sampling used for this statement(请注意,只有第一次才会自动分析,以后都要自己来手动分析)
以后就是Predicate Information (identified by operation id):
这里会出现两种情况:
(1) 如果表没有做过分析,那么CBO可以通过动态采样的方式来获取分析数据,可以正确的执行计划。
(2) 如果表分析过,但是分析信息过旧(如表在后期插入大量数据),这时CBO就不会在使用动态采样,而是使用这些旧的分析数据,从而可能导致错误的执行计划。详见下例。


四、表访问方式

1.Full Table Scan (FTS) 全表扫描

2.Index Lookup 索引扫描
There are 5 methods of index lookup:
index unique scan --索引唯一扫描
通过唯一索引查找一个数值经常返回单个ROWID,如果存在UNIQUE或PRIMARY KEY约束(它保证了语句只存取单行的话),ORACLE 经常实现唯一性扫描
当返回列是索引列时,采用唯一性扫描

Method for looking up a single key value via a unique index. always returns a single value, You must supply AT LEAST the leading column of the index to access data via the index.
index range scan --索引局部扫描
Index range scan is a method for accessing a range values of a particular column. AT LEAST the leading column of the index must be supplied to access data via the index. Can be used for range operations (e.g. > < <> >= <= between) .
使用一个索引存取多行数据,在唯一索引上使用索引范围扫描的典型情况是在谓词(WHERE 限制条件)中使用了范围操作符号(如>, < <>, >=, <=,BWTEEN)
index full scan --索引全局扫描
Full index scans are only available in the CBO as otherwise we are unable to determine whether a full scan would be a good idea or not. We choose an index Full Scan when we have statistics that indicate that it is going to be more efficient than a Full table scan and a sort. For example we may do a Full index scan when we do an unbounded scan of an index and want the data to be ordered in the index order.
index fast full scan --索引快速全局扫描,不带order by情况下常发生
Scans all the block in the index, Rows are not returned in sorted order, Introduced in 7.3 and requires V733_PLANS_ENABLED=TRUE and CBO, may be hinted using INDEX_FFS hint, uses multiblock i/o, can be executed in parallel, can be used to access second column of concatenated indexes. This is because we are selecting all of the index.
index skip scan --索引跳跃扫描,where条件列是非索引的前提情况下常发生
Index skip scan finds rows even if the column is not the leading column of a concatenated index. It skips the first column(s) during the search.
3.Rowid 物理ID扫描
This is the quickest access method available.Oracle retrieves the specified block and extracts the rows it is interested in. --Rowid扫描是最快的访问数据方式

七、运算符
1.sort    --排序,很消耗资源
There are a number of different operations that promote sorts:
(1)order by clauses (2)group by (3)sort merge join –-这三个会产生排序运算

2.filter    --过滤,如not in、min函数等容易产生
Has a number of different meanings, used to indicate partition elimination, may also indicate an actual filter step where one row source is filtering, another, functions such as min may introduce filter steps into query plans.

3.view    --视图,大都由内联视图产生(可能深入到视图基表)
When a view cannot be merged into the main query you will often see a projection view operation. This indicates that the 'view' will be selected from directly as opposed to being broken down into joins on the base tables. A number of constructs make a view non mergeable. Inline views are also non mergeable.

4.partition view     --分区视图
Partition views are a legacy technology that were superceded by the partitioning option. This section of the article is provided as reference for such legacy systems.

附:oracle优化器(Optimizer)
Oracle 数据库中优化器(Optimizer)是SQL分析和执行的优化工具,它负责指定SQL的执行计划,也就是它负责保证SQL执行的效率最高,比如优化器决定Oracle 以什么样的方式来访问数据,是全表扫描(Full Table Scan),索引范围扫描(Index Range Scan)还是全索引快速扫描(INDEX Fast Full Scan:INDEX_FFS);对于表关联查询,它负责确定表之间以一种什么方式来关联,比如HASH_JOHN还是NESTED LOOPS 或者MERGE JOIN。 这些因素直接决定SQL的执行效率,所以优化器是SQL 执行的核心,它做出的执行计划好坏,直接决定着SQL的执行效率。
          Oracle 的优化器有两种:
                   RBO(Rule-Based Optimization): 基于规则的优化器
                   CBO(Cost-Based Optimization): 基于代价的优化器
         从Oracle 10g开始,RBO 已经被弃用,但是我们依然可以通过Hint 方式来使用它。
在Oracle 10g中,CBO 可选的运行模式有2种:
(1) FIRST_ROWS(n)
           Oracle 在执行SQL时,优先考虑将结果集中的前n条记录以最快的速度反馈回来,而其他的结果并不需要同时返回。
(2)  ALL_ROWS  -- 10g中的默认值
            Oracle 会用最快的速度将SQL执行完毕,将结果集全部返回,它和FIRST_ROWS(n)的区别在于,ALL_ROWS强调以最快的速度将SQL执行完毕,并将所有的结果集反馈回来,而FIRST_ROWS(n)则侧重于返回前n条记录的执行时间。
修改CBO 模式的三种方法:
(1)  SQL 语句:
            Sessions级别:
            SQL> alter session set optimizer_mode=all_rows;
(2) 修改pfile 参数:
            OPTIMIZER_MODE=RULE/CHOOSE/FIRST_ROWS/ALL_ROWS
(3)  语句级别用Hint(/* +  ...  */)来设定
             Select /*+ first_rows(10) */ name from table;
             Select /*+ all_rows */ name from table; 

http://blog.csdn.net/gybyylx/article/details/6907588

http://blog.csdn.net/maoweiting19910402/article/details/7952314

猜你喜欢

转载自279907022.iteye.com/blog/1753430