看了此文,Oracle SQL优化文章不必再看!-程序员宅基地

看了此文,Oracle SQL优化文章不必再看!

 

第一章 看了此文,Oracle SQL优化文章不必再看!

DBAplus社群 | 2015-11-17 23:44

目录SQL优化的本质

SQL优化Road Map

2.1 制定SQL优化目标

2.2 检查执行计划

2.3 检查统计信息

2.4 检查高效访问结构

2.5 检查影响优化器的参数

2.6 SQL语句编写问题

2.7 SQL优??\x2F限制导致的执行计划差

SQL优化案例

SQL执行计划获取

4.1 如何获取准确的执行计划

4.2 看懂执行计划执行顺序

一SQL优化的本质

wpsF55B.tmp

一般来说,SQL优化是让SQL运行得更快,使SQL更快的方式有很多,比如提高索引的使用效率,或者并行查询。可以看到里面的公式:

wpsF55C.tmp

执行效率或者一般说的执行时间,是和完成一次SQL所需要访问的资源总量(S)成正比以及单位时间内能够访问的资源量(V)成反比,S越大,效率越低,V越大效率越高。 比如通过并行查询,则可以提升单位时间内访问的资源量。

当然,这仅仅是从执行时间上考虑,SQL优化肯定不仅仅是执行时间降低,应该是资源使用与执行时间降低之间寻求一种平衡,否则,盲目并行,可能提升不了效率,反而让系统资源消耗殆尽。

http\x3A?说,SQL优化的本质就是:1、缩短响应时间;2、提升系统吞吐量;3、提升系统负载能力。要使用多种手段,在提升系统吞吐量和增加系统负载能力,提高单个SQL效率之间寻求一种平衡。就是要尽量减少一条SQL需要访问的资源总量,比如走索引更好,那么不要使用全表扫描。

wpsF55D.tmp

二SQL优化Road Map

一条SQL的优化路线图如下所示:

wpsF56D.tmp

具体操作步骤:

2.1 制定SQL优化目标

获取待优化SQL、制定优化目标:从AWR、ASH、ORA工具等主动发现有问题的SQL、用户报告有性能问题DBA介入等,通过对SQL的执行情况进行了解,先初步制定SQL的优化目标。

2.2 检查执行计划

explain工具、sql*plus autotrace、dbms_xplan、10046、10053、awrsqrpt.sql等。 执行计划是我们进行SQL优化的核心内容,无计划,不优化。看执行计划有一些技巧,也有很多方式,各种方式之间是有区别的。

2.3 检查统计信息

ORACLE使用DBMS_STATS包对统计信息进行管理,涉及系统统计信息、表、列、索引、分区等对象的统计信息,统计信息是SQL能够使用正确执行计划的保证。我们知道,ORACLE CBO优化器是利用统计信息来判断正确的执行路径,JOIN方式的,因此,准确的统计信息是产生正确执行计划的首要条件。

可以从这个图看出,一条SQL产生执行计划需要经过哪些步骤,在我看来:1、正确的查询转换;2、准确的统计信息,是产生正确执行计划的重要保证。当然,还有BUG,或优化器限制等也会导致SQL效率低下,无法产生正确的执行计划。

如图所示:

wpsF56E.tmp

2.4 检��/效访问结构

重要的访问结构,诸如索引、分区等能够快速提高SQL执行效率。表存储的数据本身,如碎片过多、数据倾斜严重、数据存储离散度大,也会影响效率。

2.5 检查影响优化器的参数

2016-02-21 23:17izer_index_cost_adj、optimizer_dynamic sampling、_optimizer_mjc_enabled、_optimizer_cost_based_transformation、hash_join_enable等对SQL执行计划影响较大。比如有时候我们通过禁用_optimizer_mjc_enabled 参数,让执行计划不要使用笛卡尔积来提升效率,因为这个参数开启有很多问题,所以一般生产库都要求禁用。

还有什么能够影响执行计划呢?对,new features,每个版本的new features,引入的目的都是好的,但是实际使用中,可能触发BUG。比如11g的ACS(自适应游标共享)、automatic serial direct path(自动串行直接路径读)、extended statistics、SQL query result cache等。有的新特性会导致问题,所以需要谨慎使用。

比如11g adaptive cursor sharing,自适应游标共享,它的引入是为了解决使用绑定变量与数据倾斜值,要产生多样性执行计划。因为绑定变量是为了共享执行计划,但是数据倾斜了,有的值要求走索引,有的值要求走全表,这样与使用绑定变量就产生了矛盾。以前是通过cursor_sharing=similar这样的设置可以解决,但是有很多BUG,会产生version count过高的问题,或者我们对不同的值(如果值很少),可以写多条SQL来解决,这都不是好的方案,11g acs引入就是为了解决这些问题,让这些东西交给oracle来做。但是事与愿违,以后你们遇到执行计划一会变一下,有快有慢,首先可以检查acs有没有关闭。

alter system set “_optimizer_extended_cursor_sharing_rel”=’NONE';

2.6 SQL语句编写问题

SQL语句结构复杂、使用了不合理的语法,比如UNION代替UNION ALL都可能导致性能低下。 并不是说ORACLE优化器很强大了,我们就可以随便写SQL了,那是不正确的。SQL是一门编程语言,它能够执行的快,是有一些普遍的规则的,遵循这种编程语言特性,简化语句,才能写出好的程序。SQL语句编写出了问题,我们就需要改写,就需要调整业务,改涉及等。

2.7 SQL优化器限制导致的执行计划差

这个很重要,统计信息准确,SQL也不复杂,索引也有。。。都满足,为什么我的SQL还是差,那么得考虑优化器限制因素了。这里说1点常见的执行计划限制,当semi join与or连用的时候(也就是exists(subquery) or ...或者in (subquery) or...,如果执行计划中因为OR导致有FILTER操作符,就得注意了,可能慢的因素就和OR有关。这时候我们得改写SQL,当然改写为UNION或UNION ALL了。

OK,以上全部检查完毕,我的系统还是很差,功能还是很慢,或者已经无法从SQL本身进行调整提升性能了,那咋办?优化设计,这是终极方法。有些东西不优化设计是无法解决的,比如业务高峰期跑了一堆SQL,CPU已经很吃紧,又不给增加,突然上线一个耗资源的业务,其他SQL已无法调整。那只能优化设计,比如有些耗资源的业务可以换时间段执行等。

以上几点,是我们进行优化需要考虑的地方,可以逐步检查。当然,80%到90%的纯SQL性能调整,我们通过建立索引,收集正确统计信息,改写避免优化器限制,已经能够解决了。

三SQL优化案例

看第一个获取待优化的SQL.......如果主动优化,一般从AWR、ASH等里面找到性能差的SQL,然后优化之。

wpsF56F.tmp

wpsF580.tmp

看一个案例,占CPU 72%的SQL来自于同一模块,第一行是存储过程,通过下面绿色框住的SQL与第一行比较,主要通过EXECUTION,基本判断下面的绿色框住的SQL就是那个存储过程中的。也可以和业务确认下,OK,这些SQL的执行频次很高,因为是营销业务,如果要优化,就得搞定这些SQL。

这些SQL,单条SQL的buffer gets也就1000多点,效率还是很高的,但是因为执行的太过于频繁,所以资源消耗极大,因此,得检查下,能不能更优呢?

以第1条SQL:58q183atbusat为例:

SELECT B.ACT_ID,

B.ACT_NAME,

B.TASK_ID,

B.MKT_DICTION,

B.CUST_GROUP_ID,

NVL(B.ATTEST_FLAG, 'N'),

NVL(B.DOUWIN_FLAG, 'N'),

B.CHN_DESC,

NVL(B.SIGN_FLAG, 'N'),

B.MAX_EXECUTE_NUM

FROM (SELECT DISTINCT (ACT_ID)

FROM MK_RULECHN_REL

WHERE CHN_STATUS = '04'

AND CHN_TYPE = :B1) A,

TABLE(CAST(:B2 AS TYPE_MK_ACTIONINFO_TABLE)) B

WHERE A.ACT_ID = B.ACT_ID

SQL其实很简单,一个查询构建的A表,一个TABLE函数构建的B表关联..... 不知道大家对这个TABLE函数熟悉不熟悉?也就是将一个集合转成表,是PL/SQL里的东西

那个collection部分就是TABLE函数,下面的表走了全表扫描:

wpsF581.tmp

wpsF582.tmp

按步骤检查,发现不了问题,但是知道,可能是因为HASH JOIN导致全表扫描的问题,是否走NESTED LOOPS+INDEX更好,很显然,要检查TABLE函数大概返回多少行。

经过确认,最多也就返回200-300行,最终结果集也是几百行而已。

那么猜测,问题就在于TABLE函数,走了HASH JOIN,上面的执行计划,TABLE函数部分,ROWS为空。

来单独检查一把:返回8168行,返回8000多行,足以导致走HASH JOIN了....而事实,我们至多返回200-300行:

wpsF593.tmp

所以每个步骤返回的行,是JOIN方式选择的重要因素,可以谷歌一把,TABLE函数返回8168就是个固定值,block_size=8K的时候就是这么大,可以说,这是ORACLE的一个限制。

wpsF594.tmp

只要你用了TABLE函数,就偏向于走HASH JOIN了

http://www.oracle-developer.net/display.php?id=427 有兴趣的可以看这个链接的内容。

解决方式很多了,也就是要走NESTED LOOPS+index, 既然8168很大,那么我们就让优化器知道TABLE函数返回的行少点,才百行左右。

以下些都可以,当然也可以使用hint:use_nl等

CARDINALITY hint (9i+) undocumented;

OPT_ESTIMATE hint (10g+) undocumented;

DYNAMIC_SAMPLING hint (11.1.0.7+);

Extensible Optimiser (10g+).

因为SQL的SELECT部分只访问B,全部来自于TABLE函数,所以改写为子查询就可以了,使用子查询,自然distinct也就没有必要了,因为是semi join(半连接)。

最终改写使用cardinality hint让优化器知道B返回的行只有100行,你给我走NESTED LOOPS+INDEX,然后解决。

原来的sql:

wpsF595.tmp

修改后的sql:

wpsF596.tmp

效率提升几十倍:

wpsF5A6.tmp

一个占72%的应用,我们提升几十倍后,那对系统性能明显是极好的。最终,在执行次数增加50%的情况下,w4sd08pa主机CPU使用率由原来的高峰期平均47%的使用率降低为23%。

这个问题能够解决有两个方面:

1、猜测并测试优化器的限制(table函数固定返回行8168);2、实际返回的行200-300。两者缺一不可。如果实际返回的行就是几千上万,那么,单纯通过优化SQL,也是无法取得良好效果的。

扫描文末二维码,关注DBA+社群微信公众号(dbaplus),可下载DBA+社群技术沙龙、OOW大会、2015GOPS、DCon2015等技术盛典PPT。

四SQL执行计划获取

执行计划就是SQL调优的核心,上面的SQL也是通过看到执行计划走HASH JOIN可能有问题出发的。

wpsF5A7.tmp

那么首先要搞定2个问题:

1、如何获取我要的执行计划(准确的计划);

2、怎么看懂并找出执行计划里的问题。

4.1 如何获取准确的执行计划

获取SQL执行计划的方式:

EXPLAIN PLAN

估算

忽略绑定变量

非执行

SQL_TRACE

真实计划,需要用TKPROF工具解析

可以获得绑定变量值

EVENT 10053

真实计划

研究执行计划产生的原因

AUTOTRACE

内部使用EXPLAIN PLAN

DBMS_XPLAN

dbms_xplan.display_cursor

dbms_xplan.display_awr

真实计划

OTHERS

如awrsqrpt、sqlt、pl/sql、sql developer、toad等

大家一般怎么获取执行计划?我一般用的较多的是dbms_xplan.display_cursor,优点很明显:1、获取的是真实执行的计划;2、多种参数。还可以获取绑定变量的值方便验证。

10053是检查优化器行为的,实在搞不懂为什么走那个计划可以看看,用得较少。

10046可以检查一些等待事件的内容,也可以获取绑定变量,一般用得也比较少。

set autotrace traceonly或者explain,他们的执行计划是同一来源,记住,都来自plan_table,是估算的,可能不是真实执行的计划,可能是不准的。

所以,你看得不对劲了,就得质疑它的准确性,autotrace traceonly的好处是可以看到一致性读,物理读,返回行等,这是真实的。因为可以用一致性读,物理读来验证优化效果

其他的,比如awrsqrpt等都可以获取执行计划,不过我很少用,特别是plsq developer这种工具,F5看计划,我几乎是不用的,他也是plan table里的估算计划。如果很长,那无法分析。

建议大家看真实的计划,说一点,我经常通过alter session set statistics_level=all或者gather_plan_statistics hint,然后执行sql,然后通过

select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));来看实际执行的信息

好处很明显,能够看到执行计划每步的E-ROWS(估算的行),A-ROWS(真实的行),STARTS,BUFFER GETS,A-TIME(真实的执行时间)等信息。。。我们通过对比估算的与真实的差距,可以判断哪些表统计信息可能有问题,执行计划是不是走错了,省的我们自己根据谓词去计算这步导致返回多少行。

注意一点,如果一SQL执行很长时间,通过上面的方式来看计划,我们是可以终止的,比如执行2小时执行不玩的SQL,一般我没有耐心,最多5分钟,我就终止。终止完,通过display_cursor也是可以看出执行信息的。

比如某个步骤执行100万次,我这条SQL才能执行完,要3小时才可以,我5分钟执行了100次,我终止了SQL我要看的就是一个比例情况,可以通过这个比例来判断,哪个步骤耗的时间最长,哪里大概有问题,然后解决。

优化器很多限制的,比如刚才的TABLE函数固定返回8168,或者算法限制.....很多不准的,如果算法算出来的与真实差别很大,那可能就会导致问题。统计信息有时候也无法收集准确的,比如直方图,就有很多问题,所以12c的直方图多了几种....之前只有等高和等频直方图。

刚才的set statistics_level直接写会输出结果,我们可以让他不输出结果:

1、sql内容放到文件中,前面加上set termout off (这样可以对输出结果不输出)

2、然后display_cursor文件中

wpsF5B8.tmp

用这种东西看执行计划,有时候很方便找出问题,否则我们自己得手动根据每个步骤对应的谓词,自己写SQL去计算真实返回的行,然后再来比较,用这个,ORACLE全帮我们干好了。

4.2 看懂执行计划执行顺序

一般怎么看执行计划呢?

wpsF5B9.tmp

COPY到UE里去。

wpsF5CA.tmp

用光标大法,找到入口,最先执行的,光标定位ID=0的,然后一直缩进向下,如果被挡住了,那么这部分就是入口了。

比如ID=10的继续索引,就被ID=11的挡住了,所以第10步就是入口。

wpsF5CB.tmp

找到入口后,反向光标来,利用平行级别的最上最先执行,最右最先执行原则,来看父操作与子操作的关系,移动光标即可。

比如这里的第13步,我只需要定位光标在PARTITION这个P前面,然后向上移动,立马就知道,它的驱动表是ID=5的VIEW,因为他们是对齐的。

wpsF5DB.tmp

然后看看之间的JOIN关系是不是有问题,返回的行估算等。

执行计划最右最上最先执行规则,有个例外,大家知道不??就是通过以上规则,是不正确的。

(标量子查询)

SELECT a.employee_id,

a.department_id,

(SELECT COUNT(*) FROM emp_b b

WHERE a.department_id=b.department_id

) cnt

FROM emp_a a;

比如这个ID=2的在前面,但是它事实上是被ID=3的驱动的,也就是被emp_a驱动的,这违背了一般的执行计划顺序规则,平时注意点就行了,标量子查询谓词里会出现绑定变量,比如这里的:B1,因为每次带一个值去驱动子查询。

wpsF5DC.tmp

搞清楚执行计划怎么干,那么看执行计划看啥?

1、看JOIN的方式

2、看表的访问方式,走全表,走索引

3、看有没有一些经常影响性能的操作,比如FILTER

4、看cardinality(rows)与真实的差距

不要太过于关注COST,COST是估算的,大不一定就慢,小不一定就快……当然比如COST很小,rows返回的都是很小的,很慢。那么,我们可能得考虑统计信息是不是过旧问题。

统计信息很重要,就说一个例子:

wpsF5ED.tmp

走了索引,COST很小,一切都很完美,但是AWR现实占80%的资源。一般啥情况?单纯从SQL上看,也就是这执行计划估计不对,自己测一下,很慢。也就是COST很小,ROWS很小,走索引,很完美的计划是错误的,那么很显然,基本就是统计信息导致的了。

实际第4步走sendtime索引,应该返回1689393行,但是执行计划估算返回1行,统计信息不准确,再次检查统计信息收集日期是5月前的。

SQL> SELECT COUNT(1) FROM MSP.T_MS_MEDIA_TASK WHERE SENDTIME >=TRUNC(SYSDATE,'dd') AND MONTHDAY = TO_CHAR(SYSDATE,'mmdd') ;

? COUNT(1)

----------

? ?1689393

收集统计信息,for all columns size repeat 保持原有直方图信息

?exec DBMS_STATS.GATHER_TABLE_STATS(ownname=>'MSP',tabname=>'T_MS_MEDIA_TASK',estimate_percent=>10,method_opt=>'for all columns size repeat', no_invalidate=>false,cascade=>true,degree => 10);

返回168万行,但是现有统计信息却让cbo认为是1行,这差别也太大了。

method_opt=>'for all columns size repeat', 这里说下,更新统计信息,最好使用for all columns size repeat...

repeat的好处是啥,比如列有直方图,会给你保留,列没有统计信息会按照for all columns size 1收集。。。其他原来怎么收就怎么收。

你用一个for all columns size 1或size skewonly,或者不写(auto)都可能改变原有统计信息的收集方式,都有可能影响SQL的执行效率。

高效访问结构让SQL更快,这个不说了,主要是建索引。如何建索引也是一个很复杂的问题,说一点,一般复合索引,等值查询条件频率高的,作为前导列较好。因为直接访问可能效率比>,<...等高,后者访问了还需要过滤。

下面看下影响优化器的参数导致的性能问题。

这是10g执行计划,一个视图是UNION ALL做的,全部走索引:

wpsF5EE.tmp

但是11.2.0.4全表扫描了。

wpsF5FE.tmp

10g视图有谓词推荐,也就是查询转换里的一种OJPPD=OLD JOIN PUSH PREDICATE

升级到11.2.0.4,视图里的10张表都变成FULL SCAN。

连接谓词(A.“PAYIO_SN”=“B”.“WRTOFF_SN”)未推入到视图中。

执行时间从0.01s到4s,buffer gets从212到99w。

很显然,我要检查,统计信息没有问题,然后怎么干??看在11g里做优化器降级如何。

在11.2.0.4中使用optimizer_features_enable分别测试10.2.0.4和11.2.0.3均可谓词推入到视图中走索引。那么问题就出现在11.2.0.4了,因为11.2.0.3都是可以的。说明11.2.0.4对视图谓词推入算法有了改变。很多优化器的东西,oracle都有参数控制的,除了参数,还有各补对应的fix control。那么先检查补丁相关的

from v$system_fix_control WHERE sql_feature LIKE ‘%JPPD%’

查到了,各种开启关闭,没有用。最后看10053,分析10053,详细参看是否是BUG导致,还是优化器改进问题,参数设置问题:

wpsF5FF.tmp

10053看到默认参数被关了,检查下,大概和查询转换的两个参数:

_optimizer_cost_based_transformation

_optimizer_squ_bottomup

都被关了,当然10.2.0.4和11.2.0.3被关了也是可以的。

wpsF610.tmp

还看到基于CBO的查询转换失败,因为参数被关了,OJPPD(10g那种方式)失效了……那当然走不了,JPPD是11g的,也失效了。

基本知道执行计划如何看,关注哪些就很有用了,不要太关注啥COST前面讲了11.2.0.3都可以,到11.2.0.4不行了,那可能有2种原因:1、算法改了;2、BUG。

当然基于正常的理解,视图谓词推荐,ORACLE是必须支持的,也是不存在问题的,所以肯定有正规的解决方式。先看第2个 BUG,按理说,这种常见的东西,特别是这SQL不算复杂,ORACLE应该不会触发BUG,当然,查询转换是存在各种BUG的,11.2.0,4少了很多MOS中搜一下,比如这个JPPD,就有很多BUG,但是没有看到11.2.0.4对应的。

wpsF611.tmp

**************************

Predicate Move-Around (PM)

**************************

。。。

OJPPD: OJPPD bypassed: View semijoined to table.

JPPD: JPPD bypassed: View not on right-side of outer-join.

通过这个判断,10.2.0.4那种OJPPD,基于规则的查询转换不行了,也就是算法改变,因为cost_base_query_transformation参数关了,应该走OJPPD的。现在JPPD也走不了,因为参数被关了,这个是基于成本的查询转换才可以。

所以,这是由于算法更新导致的问题,要求必须按照ORACLE官方建议,恢复对应查询转换参数默认值:在基于COST的查询转换部分,只能走JPPD(和OJPPD类似),ORACLE建议设置CBQT参数,基于COST查询转换更准确。

开启COST查询转换,初始化优化器参数 _optimizer_cost_based_transformation设为默认值(linear)。CBQT参数有如下值:

"exhaustive", "iterative", "linear", "on", "off"。

另外通过测试得知,还需要设置_optimizer_squ_bottomup (enables unnesting of subquery in a bottom-up manner)

参数默认值true.

这个问题,但是发了SR,老外也不知道,然后我发现这2个参数恢复默认值可以,当然首先cbqt参数我认为肯定有关系,后面的squ_bottomup是测试出来的。。。后来告诉老外,老外也认可算法改变导致的问题。所以核心参数的默认值改变,是很危险的,可能影响全局,如果这两个参数不恢复,涉及数百条核心SQL就无法正常执行,也就是系统不具有可用性了。

最后说一下,经常碰到的一个优化器缺陷:

SELECT ELEMENT_TYPEA,

ELEMENT_IDA,

ELEMENT_TYPEB,

ELEMENT_IDB,

RELATION_TYPE,

EFF_RULE_ID,

EXP_RULE_ID,

CTRL_CODE,

EFF_DATE,

EXP_DATE,

GROUP_ID,

BASE_TIME_ TYPE,

POWER_RIGHT,

POSITIVE_TYPE,

BOTHWAY_FLAG

FROM DBPRODADM.pd_prc_rel a

WHERE EXISTS (SELECT 1

FROM DBPRODADM.pd_prc_dict b

WHERE a.element_ida = b.prod_prcid

AND b.prod_prc_type = '1')

AND a.exp_date > SYSDATE

AND (EXISTS (SELECT 1

FROM DBPRODADM.pd_prc_dict c

WHERE a.element_idb = c.prod_prcid

AND c.prod_prc_type = '1')

OR a.element_idb = 'X')

AND a.relation_type = '10'

当OR与semi join放在一起的时候,会触发无法进行subquery unnest的问题,也就是可能会产生FILTER,导致SQL非常缓慢,有的甚至几天,几十天也别想运行结束了。

wpsF622.tmp

第5、6步执行92万多次,那肯定慢了……问题就是有个FILTER……

FILTER类似循环,在无法unnest子查询中存在,类似标量子查询那种走法,谓词里也有绑定变量的东西。

他们唯一的好处就是内部构建HASH 表,如果匹配的重复值特别多,那么探测次数少,效率好,但是大部分时候,重复值不多,那么就是灾难了

对于这种优化器限制的,一般就是得改写了,因为SQL结构决定无法走高效的执行计划。。。因为我这里虽然走了所以,但是执行次数太多,如果执行次数少,到也无所谓。

改写后的sql:

SELECT ELEMENT_TYPEA,

ELEMENT_IDA,

ELEMENT_TYPEB,

ELEMENT_IDB,

RELATION_TYPE,

EFF_RULE_ID,

EXP_RULE_ID,

CTRL_CODE,

EFF_DATE,

EXP_DATE,

GROUP_ID,

BASE_TIME_ TYPE,

POWER_RIGHT,

POSITIVE_TYPE,

BOTHWAY_FLAG

FROM DBPRODADM.pd_prc_rel a

WHERE EXISTS (SELECT 1

FROM DBPRODADM.pd_prc_dict b

WHERE a.element_ida = b.prod_prcid

AND b.prod_prc_type = '1')

AND a.exp_date > SYSDATE

AND (EXISTS (SELECT 1

FROM DBPRODADM.pd_prc_dict c

WHERE a.element_idb = c.prod_prcid

AND c.prod_prc_type = '1')

OR a.element_idb = 'X')

AND a.relation_type = '10'

很显然,这里的条件是exists or ...那么改写得用UNION或UNION ALL了,为了避免有重复行,用UNION

select ELEMENT_TYPEA,ELEMENT_IDA,ELEMENT_TYPEB,ELEMENT_IDB,RELATION_TYPE

,EFF_RULE_ID,EXP_RULE_ID,CTRL_CODE,EFF_DATE,EXP_DATE,GROUP_ID,BASE_TIME_TYPE,

POWER_RIGHT,POSITIVE_TYPE,BOTHWAY_FLAG

from DBPRODADM.pd_prc_rel a

where exists

(select 1

from DBPRODADM.pd_prc_dict b

where a.element_ida = b.prod_prcid

and b.prod_prc_type = '1')

and a.exp_date > sysdate

and exists (select 1

from DBPRODADM.pd_prc_dict c

where a.element_idb = c.prod_prcid

and c.prod_prc_type = '1')

and a.relation_type = '10'

union

select ELEMENT_TYPEA,ELEMENT_IDA,ELEMENT_TYPEB,ELEMENT_IDB,RELATION_TYPE

,EFF_RULE_ID,EXP_RULE_ID,CTRL_CODE,EFF_DATE,EXP_DATE,GROUP_ID,BASE_TIME_TYPE,

POWER_RIGHT,POSITIVE_TYPE,BOTHWAY_FLAG

from DBPRODADM.pd_prc_rel a

where exists

(select 1

from DBPRODADM.pd_prc_dict b

where a.element_ida = b.prod_prcid

and b.prod_prc_type = '1')

and a.exp_date > sysdate

and a.element_idb = 'X'

and a.relation_type = '10';

两个分支都走HASH JOIN,starts全部为1,虽然全部是全表扫描,但是执行效率提升很明显,执行时间从12s到7s,gets从222w到4.5w之后,是否还有优化空间?

wpsF623.tmp

特别逻辑读少了很多。后续优化:

1)改写使用了UNION,是否能改成UNION ALL避免排序?

2)这么多全表扫描,是否能够让一些可以走索引?当然,这些是可以做到的,但是不是主要工作了。这个案例告诉我们,优化器是有很多限制的,不是万能的。

wpsF633.tmp

除了统计信息正确,良好的SQL结构,能够让SQL正确进行查询转换,正确的访问结构,如索引等……都是让SQL高效执行的前提条件。复杂!=低效,简单!=高效。让优化器理解,并且有合适的访问结构支持,才是王道!

简单的SQL不是快的保证,复杂的也不一定见得慢,高效的执行计划才是最重要的,索引优化SQL,最重要的就是让不好的执行计划变得好。

也就是从多个方面入手,最终达到我们的优化目标。

wpsF644.tmp

About Me

....................................................................................................................................................

本文来自于微信公众号转载文章,若有侵权,请联系小麦苗及时删除

ITPUB BLOG:http://blog.itpub.net/26736162

QQ:642808185 若加QQ请注明您所正在读的文章标题

【版权所有,文章允许转载,但须以链接方式注明源地址,否则追究法律责任】

....................................................................................................................................................

posted @ 2016-04-13 20:10 ^_^小麦苗^_^ 阅读( ...) 评论( ...)   编辑 收藏
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lihuarongaini/article/details/87495503

智能推荐

mui实现聊天功能(完整版)_umi中聊天功能的实现过程-程序员宅基地

文章浏览阅读3.9k次,点赞6次,收藏16次。前台页面代码:<!doctype html><html> <head> <meta charset="utf-8"> <title></title> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-sc..._umi中聊天功能的实现过程

穿山甲sdk激励视频广告关闭按钮引发的bug排查及解决_激励视频声音bug-程序员宅基地

文章浏览阅读3.2w次,点赞2次,收藏9次。项目中接入了穿山甲广告,其中包括图文广告和视频广告,后期发现一个偶现的问题,就是看完激励视频广告后,点击视频页面的关闭按钮,此时回到了app源生页面,UI卡住了,本来看完视频有个加分操作,现在没了。排查了代码,看看是不是自己的代码有漏洞,看了半天也没发现,然后就想,是不是穿山甲sdk的视频有问题,点击关闭按钮没有给客户端回调?为了验证这个问题,我写了个点击事件,请求激励视频并且播放,在穿山甲的回调..._激励视频声音bug

ad hoc是什么的简称_苹果ios签名有几种?分别什么价格?app分发内测有几种?-程序员宅基地

文章浏览阅读425次。随着经济的发展,苹果手机用户在不断的增加,苹果方面对于app上架也越来越严格,因此,很多app都上架不了。所以逼得很多app开发商不得不另外寻找出路,寻找其他能做苹果app分发下载的渠道。那么目前市场上关于苹果app内测分发的渠道有哪几种呢?接下来大家就和‘咕噜分发’小编一起来看一下。就目前市场上苹果分发的渠道来看,苹果app的分发下载主流主要有4种:AppStore,企业签名,超级签名,TF上架..._adhoc和tf

html页面整体隐藏,从html页面隐藏javascript / jquery脚本?-程序员宅基地

文章浏览阅读326次。最好的办法是在加载dom树后立即删除脚本标记,或者在javascript中动态创建脚本标记.无论哪种方式,如果有人想使用Web开发人员工具或Firebug,他们仍然会看到javascript.如果它在浏览器中,它将被看到.动态创建脚本标记的一个优点是,如果关闭javascript,则不会加载javascript.如果我关闭了javascript,我仍然可以在html中看到所有内容,因为您无法删除脚..._html隐藏脚本

搭建Ubuntu 10.04系统(嵌入式开发) _initrd.lz和vmlinuz下载-程序员宅基地

文章浏览阅读3.9k次。搭建Ubuntu 10.04系统(嵌入式开发) 1. 下载安装:1.1下载ubuntu:http://cdimage.ubuntu.com/releases/ 1.2 安装ubuntu:1.2.1 硬盘安装: (windows,硬盘安装ubuntu)------------ boot.ini: ------------------------[boot loader]timeout=10default=multi(0)disk(0)rdisk(0)partition(1)/WINDOWS[operatin_initrd.lz和vmlinuz下载

「Tensorflow」基于CNN的数字OCR识别_tensorflow ocr-程序员宅基地

文章浏览阅读1.9k次,点赞4次,收藏14次。导读对于人类来说,识别手写的数字是一件非常容易的事情。我们甚至不用思考,就可以看出下面的数字分别是1,2,3。本期将使用Tensorflow搭建卷积神经网络,进行手写数字的识别。代码可关注公众号 IamZLT,后台回复「手写数字识别」即可免费获取。本系列文章Part1:基于CNN的数字OCR识别part2:基于CNN的汉字识别预处理对于手写数字的初始图片如下所示。在搭建网络前我们需要对其进行预处理。▌读入图片并进行二值化图像._tensorflow ocr

随便推点

java 回朔背包问题_java回溯算法背包问题-程序员宅基地

文章浏览阅读192次。1 回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。用回溯算法解决问题的一般步骤为:一、定义一个解空间,它包含问题的解。二、利用适于搜索的方法组织解空间。三、利用深度优先法搜索解空间。四、利用限界函数避免移动到不可能产生解的子空间。问题的解空间通常是在搜索问题的解的过程中动态产生的,这是回溯算法的一个重要特性。回溯..._背包问题 回溯法 java

七、Hadoop系统应用之搭建Hadoop高可用集群(超详细步骤指导操作,WIN10,VMware Workstation 15.5 PRO,CentOS-6.7)_hadoop高可用搭建步骤-程序员宅基地

文章浏览阅读2k次,点赞2次,收藏31次。Hadoop系统应用实验之搭建Hadoop高可用集群,熟悉Hadoop高可用集群的搭建过程,WIN10系统,虚拟机软件VMware Workstation 15.5 PRO,Linux版本CentOS-6.7,超详细步骤配图详解,对新手友好。_hadoop高可用搭建步骤

hive server2源码地址在哪_0510Spark应用访问Hive报错异常分析-程序员宅基地

文章浏览阅读101次。温馨提示:如果使用电脑查看图片不清晰,可以使用手机打开文章单击文中的图片放大查看高清原图。Fayson的github:https://github.com/fayson/cdhproject提示:代码块部分可以左右滑动查看噢1故障描述运行环境说明1.RedHat7.22.CM和CDH版本为5.15.03.Spark1.6问题现象在代码中使用HiveContext对象访问Hive表ods_..._查看hiveserver2地址

python 3.8.0版本的skimage库是什么_python skimage库的安装-程序员宅基地

文章浏览阅读1.3k次。skimage库需要依赖 numpy+mkl 和scipy1、打开运行,输入cmd回车,输入python回车,查看python版本 (因为我的是python 2.7.13 win32,所以我下的是下面三个)4、将下载的文件放到Python安装目录下的Scripts目录下x:\Python xx\Scripts5、在cmd中打开Scripts目录,输入下面命令,用python的pip工具依次安装pi..._python3.8 安装 skimage

win11怎样修改开机音乐 windows11修改开机音乐的步骤教程_windows11开机音乐-程序员宅基地

文章浏览阅读4.2k次。相信很多用户都将windows开机音乐设置过自己喜欢的音乐,那么对于新的操作系统windows11当中,我们如何设置呢?这可难倒了很多网友,没关系,今天,小编就把设置windows11电脑开机声音的方法分享给大家,大家可以根据该方法设置自己喜欢的开机音乐啦。更多win11教程,可以参考小白系统网win11开机音乐的设置方法如下1、首先打开底下的开始菜单,选择设置打开。2、然后找到左侧的个性化点开,接着再选择主题打开。3、选择声音选项打开。4、在打开的声音属性页面,它的底部有个_windows11开机音乐

1、FreeRTOS及源码下载/介绍_freertos下载教程-程序员宅基地

文章浏览阅读4k次,点赞3次,收藏9次。目录1、FreeRTOS源码下载步骤2、源码介绍2.1 FreeRTOS文件夹2.2 FreeRTOS-Plus文件夹1、FreeRTOS源码下载步骤首先防问网页https://www.freertos.org/,点击Download Source接着点击右中位置的Download Source code and Projects即可自动弹出下载页面,直接下载即可..._freertos下载教程