ITPub博客

首页 > Linux操作系统 > Linux操作系统 > Oracle优化器参考(三)

Oracle优化器参考(三)

原创 Linux操作系统 作者:qgrape 时间:2008-05-31 14:28:49 0 删除 编辑

它使用多块读取的方式来读全部索引块,而且可以使用并行读取。快速全索引扫描的结果集不会排序。位图索引不能使用快速全索引扫描。

7)索引连接

 索引连接是几个索引的散列连接。如果查询的字段上都存在索引,可以使用索引连接来避免访问表。

例如:

SQL> select* from t;

           COL1            COL2            COL3            COL4

--------------- --------------- --------------- ---------------

              1               2               3               4

              1               1               3               4

              1               1               5               4

SQL> create index ind_col1 on t(col1);

索引已创建。

SQL> create index ind_col2 on t(col2);

索引已创建。

SQL> create index ind_col3 on t(col3);

索引已创建。

 

不使用索引连接:

SQL> set autotrace traceonly

SQL> select col1,col2,col3 from t where col2>0;

Execution Plan

----------------------------------------------------------

   0      SELECT STATEMENT ptimizer=CHOOSE

   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'T'

   2    1     INDEX (RANGE SCAN) OF 'IND_COL2' (NON-UNIQUE)

 

使用索引连接:

SQL> select /*+index_join(t ind_col1 ind_col2 ind_col3)*/col1,col2,col3 from t where col2>0;

Execution Plan

----------------------------------------------------------

   0      SELECT STATEMENT ptimizer=CHOOSE (Cost=70 Card=4 Bytes=156)

   1    0   VIEW OF 'index$_join$_001' (Cost=70 Card=4 Bytes=156)

   2    1     HASH JOIN

   3    2       HASH JOIN

   4    3         INDEX (RANGE SCAN) OF 'IND_COL2' (NON-UNIQUE) (Cost=3 Card=4 Bytes=156)

   5    3         INDEX (FAST FULL SCAN) OF 'IND_COL1' (NON-UNIQUE) (Cost=3 Card=4 Bytes=156)

   6    2       INDEX (FAST FULL SCAN) OF 'IND_COL3' (NON-UNIQUE) (Cost=3 Card=4 Bytes=156)

4、簇扫描

在被索引的簇中,有着相同簇键值的行存储在同一数据块中。执行簇扫描时,首先通过扫描簇索引获得被检索行的Rowid,然后使用Rowid来定位具体的行。

5、散列扫描

散列扫描就是在一个散列簇中定位数据行。在一个散列簇中,具有相同散列值的行存储在相同的数据块中。在执行散列扫描时,首先通过一个散列函数来获得散列值,然后用散列值在数据块中定位具体行。

6、表取样扫描

当FROM子句后带有SAMPLE或SAMPLE BLOCK时,会执行表取样扫描来随机检索表中的数据。

如:select* from t sample block (1);

六、处理连接

影响一个连接语句执行计划的四个重要因素是:访问路径、连接方式、连接顺序和成本评估。

1、优化器如何处理连接顺序

优化器首先确定连接的表中是否包含其结果只有一行记录的表,如果存在这样的表,优化器在对连接表排序时会把这样的表放在最前端。

如果是个外连接,含有(+)操作符的表一定排在不含(+)的表的后面。

同理被转换成ANTI-JOIN或SEMI-JOIN的子查询,子查询的表一定排在外部表的后面,但是HASH-ANTI-JOIN和HASH-SEMI-JOIN在一定情况下可以违反此顺序。

通常可以用ORDERED来指定连接顺序,但是ORDERED所指定的顺序如果违反了外连接的顺序,则ORDERED将被忽略。

2、优化器如何评估成本

嵌套循环连接,在于外表返回的每一行都要在内表中进行匹配的成本;

成本计算如下:cost of nested loop = access cost of outer + (number of rows from outer * access cost of inner)

排序合并连接,在于把两个大表读入内存并进行排序的成本;

成本计算如下:cost of merge join = access cost of A + access cost of B + (sort cost of A + sort cost of B)

散列连接,在于将小表读入内存分成若干散列表,然后由大表对每个散列表都进行一次匹配的成本;

成本计算如下:cost of hash join = access cost of smaller + (access cost of bigger * number of hash partitions of smaller)

 

以上成本计算公式不是绝对的,优化器对成本的评估还会受到其他因素的影响,比如:内存排序区过小会增加排序合并连接的成本,由于此种情况下的排序消耗了过多的CPU和I/O。多块读取会降低排序合并连接的成本,如果内表的连接字段存在索引也会降低嵌套循环连接的成本。

3、优化器可用的连接方式

1) 嵌套循环连接:NESTED LOOPS   NL

适用于外表有效基数较小,内表连接字段含有索引,且查询整体返回结果集不太大(小于1万行)的情况下。HINTS:use_nl

2) 散列连接:HASH JOIN      HJ

适用于查询整体返回大量结果集,且有较小的连接表可以放入内存作为散列表的情况下。适用散列连接要注意HASH_AREA_SIZE要足够大,可以容下散列表。如果散列表无法完全放入内存,要设置较大的临时段,从而尽量提高I/O性能。HINTS:use_hash

3) 排序合并连接:SORT MERGE JOIN    SMJ

适用于查询整体返回大量结果集,两个大表做连接,且表已经排过序的情况下。当两个表已经排过序时,使用排序合并连接的性能可能会优于散列连接。HASH_AREA_SIZE和SORT_AREA_SIZE设置过小,可能会导致优化器避开散列连接而选择排序合并连接。HINTS:use_merge

4) 迪卡尔积连接:

当两个表没有任何连接条件时会使用此连接方式。

4、一些影响优化器的初始化参数

1、OPTIMIZER_FEATURES_ENABLE:

每个版本的Oracle优化器特性都不相同,特别是做了版本升级以后一定要修改这个参数才可以使用仅被该版本支持的优化器特性。可以赋予它的值如:9.2.0、9.0.2、9.0.1、8.1.7、8.1.6等。

2、CURSOR_SHARING:

这个参数会将SQL语句中的直接量用变量来替换,存在大批直接量的OLTP系统可以考虑启用这个参数。但是要注意,绑定变量虽然可以使大量的SQL重用,减少分析时间,但是执行计划可能会不理想。通常OLTP系统适用于绑定变量,OLTP系统特点是,SQL运行频繁且时间相对较短,SQL的分析时间比重较大。如果在DSS系统中,SQL运行时间长,相比之下分析时间微不足道,好的执行计划才是最重要的,因此DSS系统不建议使用这个参数。

3、HASH_AREA_SIZE:

这是散列表的存放区域,如果使用散列连接这个参数值不能太小,否则对散列连接性能影响很大。如果是9i建议启动工作区自动管理,然后设置PGA_AGGREGATE_TARGET。

4、SORT_AREA_SIZE:

内存排序区的大小,如果排序时内存区不够会写入磁盘。9i同样建议启动工作区自动管理,然后设置PGA_AGGREGATE_TARGET。

5、HASH_JOIN_ENABLED:

只有启用这个参数,CBO在考虑连接方式的时候才会考虑散列连接。

6、OPTIMIZER_INDEX_CACHING:

这个参数表示被缓存的索引块所占的百分比,可选值的范围是0-100。这个值会影响嵌套循环连接,如果这个值设得较高,CBO将更倾向使用嵌套循环。

7、OPTIMIZER_INDEX_COST_ADJ:

优化器利用这个参数(是个百分比)把索引扫描的成本转换为等价的全表扫描的成本,然后与全表扫描的成本进行比较。缺省值100,表示索引扫描成本与全表扫描成本等价。可选值范围是0-10000。

8、OPTIMIZER_MAX_PERMUTATIONS:

这个初始参数用来设定优化器最多考虑多少种连接顺序,优化器不断的产生可能的表的连接的排列,直到排列数达到参数optimizer_max_permutations为止。一旦优化器停止产生新的排列,它将会从中选择出成本最小的排列。

9、DB_FILE_MULTIBLOCK_READ_COUNT:

这个参数表示在全表扫描或索引快速全扫描时一次I/O读的连续数据块数量(block#连续,且一次I/O不能超过extent)。

10、OPTIMIZER_MODE:

优化器模式。值为:RULE、CHOOSE、ALL_ROWS、FIRST_ROWS_n、FIRST_ROWS。

11、PARTITION_VIEW_ENABLED:

如果设置为TRUE, 该优化器将跳过分区视图中未被请求的分区,该参数还能更改基于成本的优化程序从基础表统计信息计算分区视图统计信息的方式。

12、QUERY_REWRITE_ENABLE:

如果设置为TRUE,优化器将利用可用的物化视图来重写SQL。

 

参考文档:

《Oracle Database Performance Tuning Guide 10g Release(10.1)》

   ——Part IV Optimizing SQL Statements

《Oracle9i Database Performance Tuning Guide and Reference Release2(9.2)》

   ——Part I Writing and Tuning SQL

 

 

转自:http://davis.bokee.com/2659185.html

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/12330444/viewspace-324630/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2008-04-09

  • 博文量
    223
  • 访问量
    560984