oracle优化-leading提示和ordered提示以及materialize提示

以下内容适用于oracle 10.2.0.5及其以上版本

一个查询很慢,原始SQL如下:

 1 select
 2  a.*
 3   from (select
 4          ssi.ID,
 5          ‘small_station_info‘ TB,
 6          (select sbi.name
 7             from scene_base_info sbi
 8            where sbi.id = ssi.antenna_selection) as antenna_selection,
 9          ssi.antenna_height,
10          ssi.down_angle,
11          ssi.azimuth_angle,
12          ssi.ITI_ID,
13          sa.longitude,
14          sa.latitude,
15          sa.attach_id
16           from consolidation_demand cd
17           left join demand_test_info dti
18             on cd.id = dti.cd_id
19           left join demand_plan_info dpi
20             on dti.id = dpi.tdl_id
21           left join building_plan_info bpi
22             on dpi.id = bpi.dpi_id
23           left join NEAR_FAR_PLACE_INFO nfpi
24             on bpi.id = nfpi.bpi_id
25           left join SMALL_STATION_INFO ssi
26             on nfpi.id = ssi.nfpi_id
27           left join site_attachment sa
28             on TO_NUMBER(sa.longitude) is not null
29            AND TO_NUMBER(sa.latitude) > 26.074423
30            AND TO_NUMBER(sa.latitude) < 26.077573
31            AND TO_NUMBER(sa.longitude) > 119.191148
32            AND TO_NUMBER(sa.longitude) < 119.197649
33            AND sa.attach_name =
34                substr(ssi.AZIMUTH_ANGLE_PHOTO,
35                       instr(ssi.AZIMUTH_ANGLE_PHOTO, ‘/‘, -1) + 1,
36                       length(ssi.AZIMUTH_ANGLE_PHOTO))) a
37  where a.longitude is not null

表都不大,执行计划如下:

已选择 12 行。

执行计划
----------------------------------------------------------
Plan hash value: 1917963167

---------------------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name                    | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |                         |     1 |   253 |   519   (2)| 00:00:07 |
|   1 |  TABLE ACCESS BY INDEX ROWID        | SCENE_BASE_INFO         |     1 |    14 |     1   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN                 | SCENE_BASE_INFO_PK      |     1 |       |     0   (0)| 00:00:01 |
|   3 |  VIEW                               |                         |     1 |   253 |   519   (2)| 00:00:07 |
|*  4 |   FILTER                            |                         |       |       |            |       |
|*  5 |    HASH JOIN OUTER                  |                         |     1 |   251 |   519   (2)| 00:00:07 |
|*  6 |     HASH JOIN OUTER                 |                         |    83 |  8134 |   505   (1)| 00:00:07 |
|*  7 |      HASH JOIN OUTER                |                         |    83 |  7304 |   501   (1)| 00:00:07 |
|*  8 |       HASH JOIN OUTER               |                         |    83 |  6391 |   493   (1)| 00:00:06 |
|*  9 |        HASH JOIN OUTER              |                         |    83 |  5478 |   271   (1)| 00:00:04 |
|  10 |         MERGE JOIN CARTESIAN        |                         |    36 |  2052 |    21   (0)| 00:00:01 |
|* 11 |          TABLE ACCESS BY INDEX ROWID| SITE_ATTACHMENT         |     1 |    53 |    16   (0)| 00:00:01 |
|* 12 |           INDEX RANGE SCAN          | IDX_SITE_ATTACHMENT_JWD |     1 |       |    15   (0)| 00:00:01 |
|  13 |          BUFFER SORT                |                         |  6725 | 26900 |     5   (0)| 00:00:01 |
|  14 |           INDEX FAST FULL SCAN      | PK_CONSOLIDATION_DEMAND |  6725 | 26900 |     5   (0)| 00:00:01 |
|  15 |         TABLE ACCESS FULL           | DEMAND_TEST_INFO        | 15459 |   135K|   249   (1)| 00:00:03 |
|  16 |        TABLE ACCESS FULL            | DEMAND_PLAN_INFO        |  8787 | 96657 |   221   (1)| 00:00:03 |
|  17 |       TABLE ACCESS FULL             | BUILDING_PLAN_INFO      |  3244 | 35684 |     8   (0)| 00:00:01 |
|  18 |      TABLE ACCESS FULL              | NEAR_FAR_PLACE_INFO     |   389 |  3890 |     3   (0)| 00:00:01 |
|  19 |     TABLE ACCESS FULL               | SMALL_STATION_INFO      |   594 | 90882 |    13   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("SBI"."ID"=:B1)
   4 - filter("SA"."ATTACH_NAME"=SUBSTR("SSI"."AZIMUTH_ANGLE_PHOTO",INSTR("SSI"."AZIMUTH_ANGLE_PHOTO",‘
              /‘,-1)+1,LENGTH("SSI"."AZIMUTH_ANGLE_PHOTO")))
   5 - access("NFPI"."ID"="SSI"."NFPI_ID"(+))
   6 - access("BPI"."ID"="NFPI"."BPI_ID"(+))
   7 - access("DPI"."ID"="BPI"."DPI_ID"(+))
   8 - access("DTI"."ID"="DPI"."TDL_ID"(+))
   9 - access("CD"."ID"="DTI"."CD_ID"(+))
  11 - filter("SA"."LONGITUDE" IS NOT NULL)
  12 - access(TO_NUMBER("LONGITUDE")>119.191148 AND TO_NUMBER("LATITUDE")>26.074423 AND
              TO_NUMBER("LONGITUDE")<119.197649 AND TO_NUMBER("LATITUDE")<26.077573)
       filter(TO_NUMBER("LONGITUDE") IS NOT NULL AND TO_NUMBER("LATITUDE")<26.077573 AND
              TO_NUMBER("LATITUDE")>26.074423)

这个执行计划,看起来无比正常,应该要left join的都有。

但问题的关键在于10 步骤-- MERGE JOIN CARTESIAN。笛卡尔乘积的排序合并连接,这个需要耗费很长时间。

等待这个结果要耗费几十秒,甚至要更久!
如何解决这样的问题,有以下几个方法:

  1. 重新收集每个表的统计数据--这个没有实验过,但即使那么做,可能也无效。不过从本例看,很有可能是这个导致的。
  2. 启用leading提示,结合其它提示
  3. 使用materialize提示

使用leading提示

1 select /*+ no_merge(a) no_push_pred(a) */
2  a.*
3   from (select
4         /*+ leading(cd dti dpi bpi ssi) */
5          ...) a
6  where a.longitude is not null
7 /

执行计划

已选择 12 行。

执行计划
----------------------------------------------------------
Plan hash value: 1844304918

---------------------------------------------------------------------------------------------------------
| Id  | Operation                     | Name                    | Rows  | Bytes | Cost (%CPU)| Time  |
---------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |                         |     1 |   253 |   520   (2)| 00:00:07 |
|   1 |  TABLE ACCESS BY INDEX ROWID  | SCENE_BASE_INFO         |     1 |    14 |     1   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN           | SCENE_BASE_INFO_PK      |     1 |       |     0   (0)| 00:00:01 |
|   3 |  VIEW                         |                         |     1 |   253 |   520   (2)| 00:00:07 |
|*  4 |   HASH JOIN                   |                         |     1 |   251 |   520   (2)| 00:00:07 |
|*  5 |    TABLE ACCESS BY INDEX ROWID| SITE_ATTACHMENT         |     1 |    53 |    16   (0)| 00:00:01 |
|*  6 |     INDEX RANGE SCAN          | IDX_SITE_ATTACHMENT_JWD |     1 |       |    15   (0)| 00:00:01 |
|*  7 |    HASH JOIN RIGHT OUTER      |                         | 23606 |  4564K|   503   (2)| 00:00:07 |
|   8 |     TABLE ACCESS FULL         | SMALL_STATION_INFO      |   594 | 90882 |    13   (0)| 00:00:01 |
|*  9 |     HASH JOIN RIGHT OUTER     |                         | 15459 |   679K|   490   (2)| 00:00:06 |
|  10 |      TABLE ACCESS FULL        | NEAR_FAR_PLACE_INFO     |   389 |  3890 |     3   (0)| 00:00:01 |
|* 11 |      HASH JOIN RIGHT OUTER    |                         | 15459 |   528K|   486   (2)| 00:00:06 |
|  12 |       TABLE ACCESS FULL       | BUILDING_PLAN_INFO      |  3244 | 35684 |     8   (0)| 00:00:01 |
|* 13 |       HASH JOIN RIGHT OUTER   |                         | 15459 |   362K|   477   (1)| 00:00:06 |
|  14 |        TABLE ACCESS FULL      | DEMAND_PLAN_INFO        |  8787 | 96657 |   221   (1)| 00:00:03 |
|* 15 |        HASH JOIN OUTER        |                         | 15459 |   196K|   255   (1)| 00:00:04 |
|  16 |         INDEX FAST FULL SCAN  | PK_CONSOLIDATION_DEMAND |  6725 | 26900 |     5   (0)| 00:00:01 |
|  17 |         TABLE ACCESS FULL     | DEMAND_TEST_INFO        | 15459 |   135K|   249   (1)| 00:00:03 |
---------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("SBI"."ID"=:B1)
   4 - access("SA"."ATTACH_NAME"=SUBSTR("SSI"."AZIMUTH_ANGLE_PHOTO",INSTR("SSI"."AZIMUTH_ANGLE_PH
              OTO",‘/‘,-1)+1,LENGTH("SSI"."AZIMUTH_ANGLE_PHOTO")))
   5 - filter("SA"."LONGITUDE" IS NOT NULL)
   6 - access(TO_NUMBER("LONGITUDE")>119.191148 AND TO_NUMBER("LATITUDE")>26.074423 AND
              TO_NUMBER("LONGITUDE")<119.197649 AND TO_NUMBER("LATITUDE")<26.077573)
       filter(TO_NUMBER("LONGITUDE") IS NOT NULL AND TO_NUMBER("LATITUDE")<26.077573 AND
              TO_NUMBER("LATITUDE")>26.074423)
   7 - access("NFPI"."ID"="SSI"."NFPI_ID"(+))
   9 - access("BPI"."ID"="NFPI"."BPI_ID"(+))
  11 - access("DPI"."ID"="BPI"."DPI_ID"(+))
  13 - access("DTI"."ID"="DPI"."TDL_ID"(+))
  15 - access("CD"."ID"="DTI"."CD_ID"(+))

没有笛卡尔的merge join .步骤4还是一个hash join 。
执行很快,大概可以0.17秒

使用materialize提示

1  WITH A AS
2   (select /*+MATERIALIZE */
3     .....)
4  select a.* from A WHERE a.longitude is not null

执行计划

已选择 12 行。

执行计划
----------------------------------------------------------
Plan hash value: 3536941173

--------------------------------------------------------------------------------------------------------------
| Id  | Operation                      | Name                        | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |                             | 23606 |  5832K|   700   (2)| 00:00:09 |
|   1 |  TEMP TABLE TRANSFORMATION     |                             |       |       |            |       |
|   2 |   LOAD AS SELECT               |                             |       |       |            |       |
|*  3 |    HASH JOIN RIGHT OUTER       |                             | 23606 |  5786K|   520   (2)| 00:00:07 |
|   4 |     TABLE ACCESS BY INDEX ROWID| SITE_ATTACHMENT             |     1 |    53 |    16   (0)| 00:00:01 |
|*  5 |      INDEX RANGE SCAN          | IDX_SITE_ATTACHMENT_JWD     |     1 |       |    15   (0)| 00:00:01 |
|*  6 |     HASH JOIN RIGHT OUTER      |                             | 23606 |  4564K|   503   (2)| 00:00:07 |
|   7 |      TABLE ACCESS FULL         | SMALL_STATION_INFO          |   594 | 90882 |    13   (0)| 00:00:01 |
|*  8 |      HASH JOIN RIGHT OUTER     |                             | 15459 |   679K|   490   (2)| 00:00:06 |
|   9 |       TABLE ACCESS FULL        | NEAR_FAR_PLACE_INFO         |   389 |  3890 |     3   (0)| 00:00:01 |
|* 10 |       HASH JOIN RIGHT OUTER    |                             | 15459 |   528K|   486   (2)| 00:00:06 |
|  11 |        TABLE ACCESS FULL       | BUILDING_PLAN_INFO          |  3244 | 35684 |     8   (0)| 00:00:01 |
|* 12 |        HASH JOIN RIGHT OUTER   |                             | 15459 |   362K|   477   (1)| 00:00:06 |
|  13 |         TABLE ACCESS FULL      | DEMAND_PLAN_INFO            |  8787 | 96657 |   221   (1)| 00:00:03 |
|* 14 |         HASH JOIN OUTER        |                             | 15459 |   196K|   255   (1)| 00:00:04 |
|  15 |          INDEX FAST FULL SCAN  | PK_CONSOLIDATION_DEMAND     |  6725 | 26900 |     5   (0)| 00:00:01 |
|  16 |          TABLE ACCESS FULL     | DEMAND_TEST_INFO            | 15459 |   135K|   249   (1)| 00:00:03 |
|* 17 |   VIEW                         |                             | 23606 |  5832K|   180   (2)| 00:00:03 |
|  18 |    TABLE ACCESS FULL           | SYS_TEMP_0FD9D68A2_721EF047 | 23606 |  4103K|   180   (2)| 00:00:03 |
--------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - access("SA"."ATTACH_NAME"(+)=SUBSTR("SSI"."AZIMUTH_ANGLE_PHOTO",INSTR("SSI"."AZIMUTH_ANGLE_PHOT
              O",‘/‘,-1)+1,LENGTH("SSI"."AZIMUTH_ANGLE_PHOTO")))
   5 - access(TO_NUMBER("LONGITUDE"(+))>119.191148 AND TO_NUMBER("LATITUDE"(+))>26.074423 AND
              TO_NUMBER("LONGITUDE"(+))<119.197649 AND TO_NUMBER("LATITUDE"(+))<26.077573)
       filter(TO_NUMBER("LONGITUDE"(+)) IS NOT NULL AND TO_NUMBER("LATITUDE"(+))<26.077573 AND
              TO_NUMBER("LATITUDE"(+))>26.074423)
   6 - access("NFPI"."ID"="SSI"."NFPI_ID"(+))
   8 - access("BPI"."ID"="NFPI"."BPI_ID"(+))
  10 - access("DPI"."ID"="BPI"."DPI_ID"(+))
  12 - access("DTI"."ID"="DPI"."TDL_ID"(+))
  14 - access("CD"."ID"="DTI"."CD_ID"(+))
  17 - filter("A"."LONGITUDE" IS NOT NULL)

也很快,大约0.19~0.2左右。
之所以慢,主要是因为要先生成gt表 SYS_TEMP_0FD9D68A2_721EF047。

总结

1.最好先收集统计数据

2.在收集统计数据无效的情况下,考虑使用leading提示,其次materialize提示也会破坏oracle优化器一些自以为明智的计划(优化器的不足,oracle已经提到了,这就是hint的由来)

3.dba要优化一个库,不是一个很容易的事情,需要做很多工作。

时间: 2024-12-20 20:00:06

oracle优化-leading提示和ordered提示以及materialize提示的相关文章

Oracle 12C Win8.1 X64 安装client的时候提示失败

运行里面输入 compmgmt.msc 然后删掉   系统工具-->共享文件夹-->共享里面的  C$ 然后创建新的  设置权限的时候是管理员拥有所有权限,其他用户只能访问. 重新启动安装程序就好了 Oracle 12C Win8.1 X64 安装client的时候提示失败,布布扣,bubuko.com

Oracle EBS 从Web界面进入责任时,提示不存在可用的有效责任

Oracle EBS 从Web界面进入责任时,提示不存在可用的有效责任 每次在Web界面,点击某一责任的功能时,弹出Form.会提示错误:对不起,不存在可用的有效责任. 后来找到问题的解决办法是.创建责任时.在责任keyword区域写入了中文. 因此.建议以后创建责任时.责任keyword所实用英文命名.

ORACLE优化器RBO与CBO介绍总结

RBO和CBO的基本概念 Oracle数据库中的优化器又叫查询优化器(Query Optimizer).它是SQL分析和执行的优化工具,它负责生成.制定SQL的执行计划.Oracle的优化器有两种,基于规则的优化器(RBO)与基于代价的优化器(CBO) RBO: Rule-Based Optimization 基于规则的优化器 CBO: Cost-Based Optimization 基于代价的优化器 RBO自ORACLE 6以来被采用,一直沿用至ORACLE 9i. ORACLE 10g开始,

Oracle 优化和性能调整

分析评价Oracle数据库性能主要有数据库吞吐量.数据库用户响应时间两项指标.数据库用户响应时间又可以分为系统服务时间和用户等待时间两项,即:  数据库用户响应时间=系统服务时间+用户等待时间  因此,获得满意的用户响应时间有两个途径:一是减少系统服务时间,即提高数据库的吞吐量:二是减少用户等待时间,即减少用户访问同一数据库资源的冲突率.  数据库性能优化包括如下几个部分:  调整数据结构的设计 这一部分在开发信息系统之前完成,程序员需要考虑是否使用Oracle数据库的分区功能,对于经常访问的数

oracle优化思考-双刃剑

oracle优化是一个双刃剑,特别注意这把剑用的场合:系统规划OLTP or OLAP 优化1:索引 在DML操作时,必须维护索引,如果大量的DML操作,想想看,IO是不是老高了? 索引优点:在很多时候能提高查询速度,减低IO负载 优化2: 主键使用序列,而序列的cache大小设置 如果cache设置的小,有可能造成DML锁 如果cache设置的大,DB异常关机后,已经发出的但是未提交的cache数会被丢弃,这样就造成主键的不连续 ----未完(持续更新) oracle优化思考-双刃剑,布布扣,

【Oracle 优化】Oracle数据库提高命中率及相关优化

本文是关于Oracle数据库调试与优化方面的文章,主要介绍Oracle数据库中命中率相关的问题,包括不同的算法之间性能的比对. 关于Oracle中各个命中率的计算以及相关的调优 1)Library Cache的命中率: .计算公式:Library Cache Hit Ratio = sum(pinhits) / sum(pins) SQL>SELECT SUM(pinhits)/sum(pins) FROM V$LIBRARYCACHE; 通常在98%以上,否则,需要要考虑加大共享池,绑定变量,

Oracle优化器和执行计划

1. 优化器(Optimizer)是sql分析和执行的优化工具,它负责制定sql的执行计划,负责保证sql执行效率最高,比如决定oracle以什么方式访问数据,全表扫描(full table scan)还是索引范围(index range scan)扫描,还是全索引快速扫描(index fast full scan, INDEX_FFS),对于表关联查询,是用什么方式关联.有2种优化器,RBO和CBO,从oracle 10g开始,RBO已经被弃用,但是仍可以通过hint的方式使用. 2. RBO

oracle 优化or 替换为in、exists、union all的几种写法,测试没有问题!

oracle 优化or 替换为in.exists.union的几种写法,测试没有问题! 根据实际情况用选择相应的语句吧!如果有索引,or全表扫描,in 和not in 也要慎用,否则会导致全表扫描,  select *    from T_Pro_Product   where bar_code = 'nnnmmm'      or name = 'nnnmmm'      or no = 'nnnmmm'; select * from T_Pro_Product where 'nnnmmm'

Oracle 优化器

http://blog.csdn.net/it_man/article/details/8185370一.优化器基本知识 Oracle在执行一个SQL之前,首先要分析一下语句的执行计划,然后再按执行计划去执行.分析语句的执行计划的工作是由优化器(Optimizer)来完成的.不同的情况,一条SQL可能有多种执行计划,但在某一时点,一定只有一种执行计划是最优的,花费时间是最少的. 相信你一定会用Pl/sql Developer.Toad等工具去看一个语句的执行计划,不过你可能对Rule.Choos