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

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

 select
a.*
from (select
ssi.ID,
'small_station_info' TB,
(select sbi.name
from scene_base_info sbi
where sbi.id = ssi.antenna_selection) as antenna_selection,
ssi.antenna_height,
ssi.down_angle,
ssi.azimuth_angle,
ssi.ITI_ID,
sa.longitude,
sa.latitude,
sa.attach_id
from consolidation_demand cd
left join demand_test_info dti
on cd.id = dti.cd_id
left join demand_plan_info dpi
on dti.id = dpi.tdl_id
left join building_plan_info bpi
on dpi.id = bpi.dpi_id
left join NEAR_FAR_PLACE_INFO nfpi
on bpi.id = nfpi.bpi_id
left join SMALL_STATION_INFO ssi
on nfpi.id = ssi.nfpi_id
left join site_attachment sa
on TO_NUMBER(sa.longitude) is not null
AND TO_NUMBER(sa.latitude) > 26.074423
AND TO_NUMBER(sa.latitude) < 26.077573
AND TO_NUMBER(sa.longitude) > 119.191148
AND TO_NUMBER(sa.longitude) < 119.197649
AND sa.attach_name =
substr(ssi.AZIMUTH_ANGLE_PHOTO,
instr(ssi.AZIMUTH_ANGLE_PHOTO, '/', -1) + 1,
length(ssi.AZIMUTH_ANGLE_PHOTO))) a
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提示

 select /*+ no_merge(a) no_push_pred(a) */
a.*
from (select
/*+ leading(cd dti dpi bpi ssi) */
...) a
where a.longitude is not null
/

执行计划

已选择 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提示

  WITH A AS
(select /*+MATERIALIZE */
.....)
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要优化一个库,不是一个很容易的事情,需要做很多工作。

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

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

    Oracle EBS 从Web界面进入责任时,提示不存在可用的有效责任         每次在Web界面,点击某一责任的功能时,弹出Form.会提示错误:对不起,不存在可用的有效责任.         ...

  2. [z]oracle优化http://jadethao.iteye.com/blog/1613943

    [sql] view plaincopy SQL> create table t as select 1 id,object_name from dba_objects; Table creat ...

  3. Oracle优化器介绍

    Oracle优化器介绍 本文讲述了Oracle优化器的概念.工作原理和使用方法,兼顾了Oracle8i.9i以及最新的10g三个版本.理解本文将有助于您更好的更有效的进行SQL优化工作. RBO优化器 ...

  4. ORACLE优化器RBO与CBO介绍总结

    RBO和CBO的基本概念 Oracle数据库中的优化器又叫查询优化器(Query Optimizer).它是SQL分析和执行的优化工具,它负责生成.制定SQL的执行计划.Oracle的优化器有两种,基 ...

  5. Oracle优化的几个简单步骤

    数据库优化的讨论可以说是一个永恒的主题.资深的Oracle优化人员通常会要求提出性能问题的人对数据库做一个statspack,贴出数据库配置等等.还有的人认为要抓出执行最慢的语句来进行优化.但实际情况 ...

  6. [转]ORACLE优化器RBO与CBO的区别

    RBO和CBO的基本概念 Oracle数据库中的优化器又叫查询优化器(Query Optimizer).它是SQL分析和执行的优化工具,它负责生成.制定SQL的执行计划.Oracle的优化器有两种,基 ...

  7. Oracle优化总结

    本文主要从大型数据库ORACLE环境四个不同级别的调整分析入手,分析ORACLE的系统结构和工作机理,从九个不同方面较全面地总结了ORACLE数据库的优化调整方案.关键词 ORACLE数据库 环境调整 ...

  8. ORACLE 优化

    本文主要从大型数据库ORACLE环境四个不同级别的调整分析入手,分析ORACLE的系统结构和工作机理,从九个不同方面较全面地总结了 ORACLE数据库的优化调整方案. 关键词 ORACLE数据库 环境 ...

  9. Oracle 优化器_表连接

    概述 在写SQL的时候,有时候涉及到的不仅只有一个表,这个时候,就需要表连接了.Oracle优化器处理SQL语句时,根据SQL语句,确定表的连接顺序(谁是驱动表,谁是被驱动表及 哪个表先和哪个表做链接 ...

随机推荐

  1. 前端之CSS——CSS选择器

    一.CSS介绍 为什么需要CSS(CSS的作用)? 在没有CSS之前,我们想要修改HTML元素的样式需要为每个HTML元素单独定义样式属性,当HTML内容非常多时,就会定义很多重复的样式属性,并且修改 ...

  2. cf1072B. Curiosity Has No Limits(枚举)

    题意 题目链接 给出两个序列\(a, b\),求出一个序列\(t\),满足 \[a_i = t_i | t_{i + 1}\] \[b_i = t_i \& t_{i + 1}\] 同时,\( ...

  3. CNN 和RNN 中input 长度不一致问题

    转自:https://www.jianshu.com/p/86d667ee3c62,感谢分享! pad_sequences & Masking layer 上面提到,文本数据也可以用CNN来处 ...

  4. 大数据的正确用法你get到了吗?

    Azure 镜像市场已于2016年9月21日正式上线,在这个统一的集成平台中,客户可以轻松地浏览.搜索和选择一系列来自第三方的应用和解决方案,并可以将其快速一键部署到 Azure 实例当中. 在移动为 ...

  5. Java框架安全

    (一)Mybatis注入问题 Mybatis是目前比较常用的ORM的框架,一般与SpringMVC框架整合较多,但使用不当会有SQL注入的风险. Mybatis里mapper中SQL语句的写法支持两种 ...

  6. #学习笔记#e2e学习使用(二)

    前言: <#学习笔记#e2e学习使用(一)>主要记录了Vue项目的创建到e2e环境的搭建,以及期间遇到的各种问题和解决方法.本文建立在基础测试环境搭建完毕能正确运行的情况下,编写测试代码, ...

  7. June 03rd 2017 Week 22nd Saturday

    Truth and roses have thorns about them. 真理和玫瑰,身边都有刺. Yesterday, I met with a young, beautiful profes ...

  8. March 14 2017 Week 11 Tuesday

    Thinking will not overcome fear but action will. 空想终日惶恐,行动方可无惧. As the deadline comes closer and clo ...

  9. Oracle服务端及客户端搭建帮助文档

    Oracle服务端及客户端搭建帮助文档 目录 简介 Oracle服务端安装 Oracle客户端安装 PLSQL安装 登录测试 系统配置修改 用户操作 解锁账户.密码 创建账户及密码 配置监听文件 监听 ...

  10. 如何使用Kubernetes的configmap通过环境变量注入到pod里

    在Kubernetes官网里,有这样一篇文章,提到了Kubernetes里的一个最佳实践就是把应用代码同配置信息分开,一种方式就是使用Kubernetes 1.2里引入的configmap概念. ht ...