利用ordered hints优化SQL
SQL_ID 4g70n3k9bqc5v, child number 0
-------------------------------------
MERGE INTO YJBZH_GRXDFHZMXJL GRXDFHZMXJL USING ( SELECT A.AGMT_ID AS
AGMT_ID, B.CUST_NAME AS CUST_NAME FROM DWF.F_AGT_CADB_BOOK_H A,
DWF.F_AGT_SAVB_BASICINFO_H B WHERE A.START_DT <= TO_DATE(:B1
,'yyyy-mm-dd') AND A.END_DT > TO_DATE(:B1 ,'yyyy-mm-dd') AND B.START_DT
<= TO_DATE(:B1 ,'yyyy-mm-dd') AND B.END_DT > TO_DATE(:B1 ,'yyyy-mm-dd')
AND A.MASTER_CARD_NO = B.AGMT_ID ) SAVB_BASICINFO ON (
RTRIM(GRXDFHZMXJL.DFZH) = SAVB_BASICINFO.AGMT_ID AND CJRQ =
TO_CHAR(TO_DATE(:B1 , 'YYYY-MM-DD'),'yyyymmdd') ) WHEN MATCHED THEN
UPDATE SET GRXDFHZMXJL.DFHM = SAVB_BASICINFO.CUST_NAME
Plan hash value: 2923259190
---------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------------------
| 0 | MERGE STATEMENT | | | | 44331 (100)| |
| 1 | MERGE | YJBZH_GRXDFHZMXJL | | | | |
| 2 | VIEW | | | | | |
| 3 | NESTED LOOPS | | 1 | 1862 | 44331 (1)| 00:08:52 |
| 4 | NESTED LOOPS | | 15 | 1862 | 44331 (1)| 00:08:52 |
| 5 | MERGE JOIN CARTESIAN | | 1 | 1808 | 44313 (1)| 00:08:52 |
|* 6 | TABLE ACCESS FULL | YJBZH_GRXDFHZMXJL | 1 | 1762 | 26057 (1)| 00:05:13 |
| 7 | BUFFER SORT | | 2120K| 93M| 18256 (2)| 00:03:40 |
|* 8 | TABLE ACCESS FULL | F_AGT_SAVB_BASICINFO_H | 2120K| 93M| 18256 (2)| 00:03:40 |
|* 9 | INDEX RANGE SCAN | F_AGT_CADB_BOOK_H_IDX2 | 15 | | 2 (0)| 00:00:01 |
|* 10 | TABLE ACCESS BY INDEX ROWID| F_AGT_CADB_BOOK_H | 1 | 54 | 18 (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
6 - filter("CJRQ"=TO_CHAR(TO_DATE(:B1,'YYYY-MM-DD'),'yyyymmdd'))
8 - filter(("B"."START_DT"<=TO_DATE(:B1,'yyyy-mm-dd') AND
"B"."END_DT">TO_DATE(:B1,'yyyy-mm-dd')))
9 - access("A"."AGMT_ID"=RTRIM("GRXDFHZMXJL"."DFZH") AND
"A"."END_DT">TO_DATE(:B1,'yyyy-mm-dd') AND "A"."END_DT" IS NOT NULL)
10 - filter(("A"."MASTER_CARD_NO" IS NOT NULL AND "A"."START_DT"<=TO_DATE(:B1,'yyyy-mm-dd')
AND "A"."MASTER_CARD_NO"="B"."AGMT_ID"))
select count(*) from YJBZH_GRXDFHZMXJL
--0
后来发现多个merge在一个会话里,添加日志后表数据有20W+
select count(*) from dwf.F_AGT_SAVB_BASICINFO_H B where (("B"."START_DT"<=TO_DATE(20131231,'yyyy-mm-dd') AND
"B"."END_DT">TO_DATE(20131231,'yyyy-mm-dd')))
---返回了1071795条记录
那此时ID=5 就傻逼了,实际需要至少返回1071795 然后作为驱动集去驱动ID=9 那么F_AGT_CADB_BOOK_H_IDX2 需要扫描1071795次,此时SQL肯定跑不出来
这时候关联顺序变成了YJBZH_GRXDFHZMXJL和F_AGT_SAVB_BASICINFO_H进行笛卡尔积,产生的结果集在和F_AGT_CADB_BOOK_H进行关联,但是看SQL并不是这样
正确的关联顺序是F_AGT_CADB_BOOK_H和F_AGT_SAVB_BASICINFO_H关联产生的结果集在和YJBZH_GRXDFHZMXJL关联。
添加hints:
ORDERED提示强制Oracle按照From子句中表出现的顺序进行表连接。
通过ORDERED提示,可以避免CBO SQL解析过程中的表连接评估,从而避免Oracle产生错误的执行计划,或者强制Oracle按照我们指定的方式执行。在很多时候,当我们清楚地了解数据结构和数据分布之后,就可以通过ORDERED提示来提高SQL性能。
SQL_ID cw628tpmjcbjv, child number 0
-------------------------------------
MERGE /*+ordered*/ INTO YJBZH_GRXDFHZMXJL GRXDFHZMXJL USING ( SELECT
A.AGMT_ID AS AGMT_ID, B.CUST_NAME AS CUST_NAME FROM
DWF.F_AGT_CADB_BOOK_H A, DWF.F_AGT_SAVB_BASICINFO_H B WHERE A.START_DT
<= TO_DATE(:B1 ,'yyyy-mm-dd') AND A.END_DT > TO_DATE(:B1 ,'yyyy-mm-dd')
AND B.START_DT <= TO_DATE(:B1 ,'yyyy-mm-dd') AND B.END_DT > TO_DATE(:B1
,'yyyy-mm-dd') AND A.MASTER_CARD_NO = B.AGMT_ID ) SAVB_BASICINFO ON (
RTRIM(GRXDFHZMXJL.DFZH) = SAVB_BASICINFO.AGMT_ID AND CJRQ =
TO_CHAR(TO_DATE(:B1 , 'YYYY-MM-DD'),'yyyymmdd') ) WHEN MATCHED THEN
UPDATE SET GRXDFHZMXJL.DFHM = SAVB_BASICINFO.CUST_NAME
Plan hash value: 2400855618
--------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------------
| 0 | MERGE STATEMENT | | | | | 138K(100)| |
| 1 | MERGE | YJBZH_GRXDFHZMXJL | | | | | |
| 2 | VIEW | | | | | | |
|* 3 | HASH JOIN | | 1 | 1862 | | 138K (2)| 00:27:39 |
|* 4 | TABLE ACCESS FULL | YJBZH_GRXDFHZMXJL | 1 | 1762 | | 26057 (1)| 00:05:13 |
|* 5 | HASH JOIN | | 11M| 1074M| 374M| 112K (2)| 00:22:25 |
|* 6 | TABLE ACCESS FULL| F_AGT_CADB_BOOK_H | 5951K| 306M| | 69245 (2)| 00:13:51 |
|* 7 | TABLE ACCESS FULL| F_AGT_SAVB_BASICINFO_H | 2120K| 93M| | 18256 (2)| 00:03:40 |
--------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("A"."AGMT_ID"=RTRIM("GRXDFHZMXJL"."DFZH"))
4 - filter("CJRQ"=TO_CHAR(TO_DATE(:B1,'YYYY-MM-DD'),'yyyymmdd'))
5 - access("A"."MASTER_CARD_NO"="B"."AGMT_ID")
6 - filter(("A"."MASTER_CARD_NO" IS NOT NULL AND "A"."START_DT"<=TO_DATE(:B1,'yyyy-mm-dd')
AND "A"."END_DT">TO_DATE(:B1,'yyyy-mm-dd')))
7 - filter(("B"."START_DT"<=TO_DATE(:B1,'yyyy-mm-dd') AND
"B"."END_DT">TO_DATE(:B1,'yyyy-mm-dd')))
利用ordered hints优化SQL的更多相关文章
- 【转】利用 force index优化sql语句性能
今天写了一个统计sql,在一个近亿条数据的表上执行,200s都查不出结果.SQL如下: select customer,count(1) c from upv_** where created bet ...
- 利用 force index优化sql语句性能
[转自:https://blog.csdn.net/bruce128/article/details/46777567]并进行总结 今天写了一个统计sql,在一个近亿条数据的表上执行,200s都查不出 ...
- 再一次利用with as 优化SQL
上海的一个哥们问我有个SQL跑了4个小时都没跑完,实在受不了了,找我优化一下.我确实挺佩服他的,要是我遇到跑了几分钟的,就受不了了. SQL语句和执行计划如下: --sql id:1qbbw3th4x ...
- 利用查询提示优化SQL
数据库环境:SQL SERVER 2005 我们来看一下SQL语句及对应的数据量 SELECT COUNT(*) FROM cinvout_02 a WHERE ( a.dept_id IN ( SE ...
- 利用DBMS_SQLTUNE优化SQL
DBMS_SQLTUNE优化SQL是在oracle10g才出来的新特性,使用它能很大程度上方便对sql的分析和优化.执行DBMS_SQLTUNE包进行sql优化需要有advisor的权限: stat& ...
- [转]利用/*+Ordered*/提高查询性能
[转]利用/*+Ordered*/提高查询性能 2009-02-06 10:46:27| 分类: Oracle | 标签: |字号大中小 订阅 消耗在准备利用Oracle执行计划机制提高查询性能 ...
- advisor调优工具优化sql(基于sql_id)
advisor调优工具优化sql(基于sql_id) 问题背景:客户反馈数据库迁移后cpu负载激增,帮忙查看原因 解决思路:1> 查看问题系统发现有大量的latch: cache buffers ...
- 【转】使用SQL Tuning Advisor STA优化SQL
SQL优化器(SQL Tuning Advisor STA)是Oracle10g中推出的帮助DBA优化工具,它的特点是简单.智能,DBA值需要调用函数就可以给出一个性能很差的语句的优化结果.下面介绍一 ...
- sql语句优化SQL Server
MS SQL Server查询优化方法查询速度慢的原因很多,常见如下几种 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2.I/O吞吐量小,形成了 ...
随机推荐
- Qt 学习之路:存储容器
存储容器(containers)有时候也被称为集合(collections),是能够在内存中存储其它特定类型的对象,通常是一些常用的数据结构,一般是通用模板类的形式.C++ 提供了一套完整的解决方案, ...
- Qt 属性
Qt提供了一套和一些编译器提供商也提供的属性系统类似的完善的属性系统.然而,作为一个不依赖编译器和平台的库,Qt不能依赖像__property或者[property]那样的非标准编译器特征.我们的 ...
- [转] 剖析 epoll ET/LT 触发方式的性能差异误解(定性分析)
http://blog.chinaunix.net/uid-17299695-id-3059078.html PS:Select和Poll都是水平触发,epoll默认也是水平触发 ET模式仅当状态发生 ...
- RHEL7下PXE+Apache+Kickstart无人值守安装操作系统
RHEL7下PXE+Apache+Kickstart无人值守安装操作系统 1.配置yum源 vim /etc/yum.repos.d/development.repo [development] na ...
- Django Errors Archive
记录使用 Django 开发中遇到的问题,备用 1. 版本要选好,最好安装上 pip,可以省很多麻烦 2. 如果使用 Postgresql,选 8.1 之后的版本,免去 Retruning 之类的错误 ...
- MeasureSpec
在自定义View和ViewGroup的时候,我们经常会遇到int型的MeasureSpec来表示一个组件的大小,这个变量里面不仅有组件的尺寸大小,还有大小的模式. 这个大小的模式,有点难以理解.在系统 ...
- 【转载】ASP.NET线程安全与静态变量的生命周期浅谈
ASP.NET线程安全所涉及的是什么呢?让我们先来看看静态变量的生命周期问题,下面是我理解的静态变量的生命周期: void Application_Start开始 void Application_E ...
- oracle死锁模拟
环境介绍: 用户test01 创建表tab01,用户test02创建表tab02.Test01 更新tab01不提交,test02 更新表tab02不提交.然后test01 更新test02下的表ta ...
- OC - 19.pthread和NSThread
简介 恰当的使用多线程编程可以提供任务的执行效率和系统资源的利用率 多线程是为了提高资源利用率,和应用程序的响应速度,多个线程共享应用资源 每个应用程序都有一个主线程,通常用来做UI界面刷新等 比较耗 ...
- UIScrollView不能响应touch事件的解决办法
UIScrollView本身事是不支持touch的,我们可以给她添加拓展 #import "UIScrollView+util.h" @implementation UIScrol ...