oracle优化-leading提示和ordered提示以及materialize提示
以下内容适用于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。笛卡尔乘积的排序合并连接,这个需要耗费很长时间。
等待这个结果要耗费几十秒,甚至要更久!
如何解决这样的问题,有以下几个方法:
- 重新收集每个表的统计数据--这个没有实验过,但即使那么做,可能也无效。不过从本例看,很有可能是这个导致的。
- 启用leading提示,结合其它提示
- 使用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提示的更多相关文章
- Oracle EBS 从Web界面进入责任时,提示不存在可用的有效责任
Oracle EBS 从Web界面进入责任时,提示不存在可用的有效责任 每次在Web界面,点击某一责任的功能时,弹出Form.会提示错误:对不起,不存在可用的有效责任. ...
- [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 ...
- Oracle优化器介绍
Oracle优化器介绍 本文讲述了Oracle优化器的概念.工作原理和使用方法,兼顾了Oracle8i.9i以及最新的10g三个版本.理解本文将有助于您更好的更有效的进行SQL优化工作. RBO优化器 ...
- ORACLE优化器RBO与CBO介绍总结
RBO和CBO的基本概念 Oracle数据库中的优化器又叫查询优化器(Query Optimizer).它是SQL分析和执行的优化工具,它负责生成.制定SQL的执行计划.Oracle的优化器有两种,基 ...
- Oracle优化的几个简单步骤
数据库优化的讨论可以说是一个永恒的主题.资深的Oracle优化人员通常会要求提出性能问题的人对数据库做一个statspack,贴出数据库配置等等.还有的人认为要抓出执行最慢的语句来进行优化.但实际情况 ...
- [转]ORACLE优化器RBO与CBO的区别
RBO和CBO的基本概念 Oracle数据库中的优化器又叫查询优化器(Query Optimizer).它是SQL分析和执行的优化工具,它负责生成.制定SQL的执行计划.Oracle的优化器有两种,基 ...
- Oracle优化总结
本文主要从大型数据库ORACLE环境四个不同级别的调整分析入手,分析ORACLE的系统结构和工作机理,从九个不同方面较全面地总结了ORACLE数据库的优化调整方案.关键词 ORACLE数据库 环境调整 ...
- ORACLE 优化
本文主要从大型数据库ORACLE环境四个不同级别的调整分析入手,分析ORACLE的系统结构和工作机理,从九个不同方面较全面地总结了 ORACLE数据库的优化调整方案. 关键词 ORACLE数据库 环境 ...
- Oracle 优化器_表连接
概述 在写SQL的时候,有时候涉及到的不仅只有一个表,这个时候,就需要表连接了.Oracle优化器处理SQL语句时,根据SQL语句,确定表的连接顺序(谁是驱动表,谁是被驱动表及 哪个表先和哪个表做链接 ...
随机推荐
- java位运算之简单了解
1.十进制转化为二进制 将正整数转化为二进制的方法“除2取余,逆序排列”. 2.二进制转化为十进制 表示整数的二进制,第一位为标志位,0代表为正整数,位数从右开始,第一个位数为0,各位位数记作n,取各 ...
- The twentyth day
10th Dec 2018 Cause It's hard for me to lose in my life I've found 因为失去你是一种煎熬 Only time will tell a ...
- 关于js 中函数的参数
var a = 100; function test(a){ a++; //a(形参)是局部变量 console.log(a); } test(a); console.log(a); //结果是 10 ...
- 《ArcGIS Runtime SDK for Android开发笔记》——(15)、要素绘制Drawtools3.0工具DEMO
1.前言 移动GIS项目开发中点线面的要素绘制及编辑是最常用的操作,在ArcGIS Runtime SDK for iOS 自带AGSSketchLayer类可以帮助用户快速实现要素的绘制,图形编辑. ...
- matlab练习程序(弧形投影)
这个其实也算是圆柱体投影了,不过上一篇文章是从正面看,得到的是凸形的结果,而这个是从反面看,得到的是凹形的结果. 计算公式就不写了,大致介绍一下,计算公式中关于x坐标求法和上篇一样,y坐标则正好是上篇 ...
- EL表达式的内置对象
在EL表达式中,无需创建就可以使用的对象称之为EL隐藏(隐含.内置)对象.在EL中一共有11个隐藏对象,它们都与Map相似.其中10是Map,一个是 PageContext. 参数隐藏对象 这些隐藏对 ...
- 1977年提出的OSI七层模型
OSI七层模型: 7应用层 数据用户接口,提供人操作软件的接口 6表示层 数据的表现形式,特定的功能实现,比如数据加密.数据传输的编码等,一般由软件完成 ...
- Laravel 单元测试-模拟认证的用户
在 Laravel 编写单元测试时经常会遇到需要模拟认证用户的时候,比如新建文章.创建订单等,那么在 Laravel unit test 中如何来实现呢? 官方解决方法 Laravel 的官方文档中的 ...
- 【CentOS】在Centos7 下无图形界面安装 Oracle11g
目标 - 在虚拟机CentOS7中无图形界面安装Oracle11G R2版本 ① 系统要求以及准备 1. 物理内存不小于1G: 查看方式: # grep MemTotal /proc/meminfo ...
- 第五章 LED的魔性操作
想必大家都见过城市里漂亮的led广告牌吧,这一节我将带大家学习这些LED广告牌最基本的实现原理. 初识LED 接线方法:D1~D8从接23~37号数字端口,v1和前面的针头分别接41号和39号数字端口 ...