巧用Oracle执行计划机制提高查询性能
本文主要讲述了Oracle内部产生执行计划的机制,通过这种机制你可以控制Oracle花费在评估连接顺序的时间数量,并且能在大体上提高查询性能。 电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站+ v; m# b+ `% |1 P
www.520diannao.com9 E4 Z. _; s- }+ T' n8 `" S
我爱电脑技术论坛; _& `/ V. I) o9 b c0 c0 a! l' i
准备执行SQL语句
0 k+ ]( c, J0 t R' N, Xwww.520diannao.com我爱电脑技术社区--打造最好的电脑技术自学交流平台+ F9 I$ p! z2 O, C4 K8 M0 t n
2 R, h2 O3 v8 S' B7 }0 N+ dwww.520diannao.com当SQL语句进入Oracle的库缓存后,在该语句准备执行之前,将执行下列步骤: + r3 O! h o/ m/ j
打造最好的电脑自学交流论坛" E9 E3 A) C' @: A5 G9 W
7 n! j& l$ l+ w e4 \5 O我爱电脑技术论坛(1) 语法检查:检查SQL语句拼写是否正确和词序。
4 |2 p# K4 L2 x! E我爱电脑技术社区--打造最好的电脑技术自学交流平台
j: h- w" |2 @3 E( A* I) n. x. K9 j我爱电脑技术社区--打造最好的电脑技术自学交流平台
. k" F: @: S% a/ F(2) 语义分析:核实所有的与数据字典不一致的表和列的名字。 我爱电脑技术论坛! F- r, I4 S/ W7 `% V% v9 g
电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站' i+ c" i( A: U! l5 K4 V
我爱电脑技术社区--打造最好的电脑技术自学交流平台7 V9 A/ X$ V4 {6 b! K
(3) 轮廓存储检查:检查数据字典,以确定该SQL语句的轮廓是否已经存在。
. n& u9 j) S" _$ n6 e电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站我爱电脑技术社区--打造最好的电脑技术自学交流平台/ J! D6 x9 i2 {9 _1 b+ n! V
! Q& A) G8 t, m我爱电脑技术社区--打造最好的电脑技术自学交流平台(4) 生成执行计划:使用基于成本的优化规则和数据字典中的统计表来决定最佳执行计划。
7 c+ |- n* E& r8 J5 T. f- Q2 r, Kwww.520diannao.com+ k6 u( t& x! B) O- K* Z
打造最好的电脑自学交流论坛7 Q( Y8 M4 o: W4 K0 ?
(5) 建立二进制代码:基于执行计划,Oracle生成二进制执行代码。 - k* P# k; c H6 Z2 j8 y3 a
9 a5 y# T* _( w
我爱电脑技术论坛( \2 H1 ?+ k x# `4 ?
一旦为执行准备好了SQL语句,以后的执行将很快发生,因为Oracle认可同一个SQL语句,并且重用那些语句的执行。然而,对于生成特殊的SQL语句,或嵌入了文字变量的SQL语句的系统,SQL执行计划的生成时间就很重要了,并且前一个执行计划通常不能够被重用。对那些连接了很多表的查询,Oracle需要花费大量的时间来检测连接这些表的适当顺序。 www.520diannao.com/ {6 h% `5 a e' z
$ s$ C+ Q/ b% Hwww.520diannao.com4 D) Y G+ z7 c( m6 n; p: Y5 N
评估表的连接顺序 www.520diannao.com" p" l0 u/ T! U; e1 e4 {
' j! h4 Q& \( d$ `/ t3 ?: H8 S电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站
+ G. U, Y6 u2 Z4 P6 E0 Z打造最好的电脑自学交流论坛在SQL语句的准备过程中,花费最多的步骤是生成执行计划,特别是处理有多个表连接的查询。当Oracle评估表的连接顺序时,它必须考虑到表之间所有可能的连接。例如:六个表的之间连接有720(6的阶乘,或6 * 5 * 4 * 3 * 2 * 1 = 720)种可能的连接线路。当一个查询中含有超过10个表的连接时,排列的问题将变得更为显著。对于15个表之间的连接,需要评估的可能查询排列将超过1万亿(准确的数字是1,307,674,368,000)种。
4 t. E6 V7 K6 [. x p8 k( L我爱电脑技术社区--打造最好的电脑技术自学交流平台
H- ~0 z5 ~( w+ a9 p电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站
4 V& t$ c( V& o% ]打造最好的电脑自学交流论坛使用optimizer_search_limit参数来设定限制
6 n2 a1 A# a# I9 _我爱电脑技术社区--打造最好的电脑技术自学交流平台www.520diannao.com6 k2 y7 ?% W5 u# }! v' h
0 A; p2 Q N% ^3 g$ {6 hwww.520diannao.com通过使用optimizer_search_limit参数,你能够指定被优化器用来评估的最大的连接组合数量。使用这个参数,我们将能够防止优化器消耗不定数量的时间来评估所有可能的连接组合。如果在查询中表的数目小于optimizer_search_limit的值,优化器将检查所有可能的连接组合。
. T! k+ v- v k( w0 O我爱电脑技术论坛
0 V2 j6 d- l4 E' Q: `打造最好的电脑自学交流论坛
/ Y( ~. O' ^$ @2 X我爱电脑技术社区--打造最好的电脑技术自学交流平台例如:有五个表连接的查询将有120(5! = 5 * 4 * 3 * 2 * 1 = 120)种可能的连接组合,因此如果optimizer_search_limit等于5(默认值),则优化器将评估所有的120种可能。optimizer_search_limit参数也控制着调用带星号的连接提示的阀值。当查询中的表的数目比optimizer_search_limit小时,带星号的提示将被优先考虑。 www.520diannao.com8 D( _: u; v3 y
我爱电脑技术论坛% I! E6 K1 o* w+ a
我爱电脑技术社区--打造最好的电脑技术自学交流平台: k# J# y5 X ^$ S1 r$ K
另一个工具:参数optimizer_max_permutations 0 [( V+ E; i1 A7 t/ I
打造最好的电脑自学交流论坛1 r @1 i. n# ^0 j
我爱电脑技术论坛0 I/ w+ F$ S1 J4 g- @/ x
初始化参数optimizer_max_permutations定义了优化器所考虑组合数目的上限,且依赖于初始参数optimizer_search_limit。optimizer_max_permutations的默认值是80,000。 电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站7 ?8 I9 J* ] l7 y" L
$ N# T" p: I0 @; I3 |4 C我爱电脑技术论坛
# e( @' Q9 k. [1 u. S打造最好的电脑自学交流论坛参数optimizer_search_limit和optimizer_max_permutations一起来确定优化器所考虑的组合数目的上限:除非(表或组合数目)超过参数optimizer_search_limit 或者 optimizer_max_permutations设定的值,否则优化器将生成所有可能的连接组合。一旦优化器停止评估表的连接组合,它将选择成本最低的组合。 电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站. p* T5 C8 o X( {3 t
电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站8 {* D% p+ E" c: u! J, ?
. q1 t: Q, j7 E, M9 f3 p电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站
9 K! D$ |6 G! g9 X3 O3 \我爱电脑技术社区--打造最好的电脑技术自学交流平台使用ordered提示指定连接顺序
' e, I P9 I5 P
: P+ Q* E0 O; @我爱电脑技术论坛我爱电脑技术社区--打造最好的电脑技术自学交流平台( k4 e2 F4 n2 P1 X0 p) f/ x% G! F
你能够设定优化器所执行的评估数目的上限。但是即使采用有很高价值的排列评估,我们仍然拥有使优化器可以尽早地放弃复杂的查询的重要机会。回想一下含有15个连接查询的例子,它将有超过1万亿种的连接组合。如果优化器在评估了80,000个组合后停止,那么它才仅仅评估了0.000006%的可能组合,而且或许还没有为这个巨大的查询找到最佳的连接顺序。
( z3 I# a+ F1 D; G* K! b: e8 J* W我爱电脑技术社区--打造最好的电脑技术自学交流平台
7 K# U {( }$ l: ]! m. i打造最好的电脑自学交流论坛www.520diannao.com' A+ W- b0 E) \8 e$ ?9 o
在Oracle SQL中解决此问题的最好的方法是手工指定表的连接顺序。为了尽快创建最小的解决方案集,这里所遵循的规则是将表结合起来,通常优先使用限制最严格的WHERE子句来连接表。
- \8 w' c( V: K) M% M, q# [我爱电脑技术社区--打造最好的电脑技术自学交流平台
[/ b+ E# f4 h, |, w" a我爱电脑技术社区--打造最好的电脑技术自学交流平台
+ l% f# C1 e& ` f2 R- B电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站下面的代码是一个查询执行计划的例子,该例子在emp表的关联查询上强制执行了嵌套的循环连接。注意,我已经使用了ordered提示来直接最优化表的评估顺序,最终它们表现在WHERE子句上。
& M' l; y" S$ L9 i9 H
: [% t ], M9 k我爱电脑技术论坛6 J, {9 U& q: z; G1 U/ h
select /*+ ordered use_nl(bonus) parallel(e, 4) */我爱电脑技术社区--打造最好的电脑技术自学交流平台0 b7 b* \- _ f6 z' N3 S) q0 K) q/ p
4 [, y( i2 i/ p! |3 e电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站e.ename,
6 L5 t7 M$ v. o4 X 我爱电脑技术社区--打造最好的电脑技术自学交流平台 q1 ^ l K1 g
hiredate,
# ]8 T, Z( o a. S. v4 h2 y V我爱电脑技术社区--打造最好的电脑技术自学交流平台
* Z$ M7 _- b* n6 K+ m电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站b.comm.
3 C# T s2 W+ ?" w电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站 www.520diannao.com* \! t5 Q$ f. M- I. u& G. e! R
from
9 K9 X) F4 e/ @; V, h! n4 R我爱电脑技术论坛
9 {! S( ?6 t3 Q; K+ \emp e,我爱电脑技术论坛. r1 c g! N- Q/ ~
我爱电脑技术论坛' V1 O0 E! s% O2 B
bonus b+ i( `8 Q9 [3 v$ V7 Q' l8 m' C
我爱电脑技术社区--打造最好的电脑技术自学交流平台+ d; {8 K) n; P8 ]! f. l9 J
where打造最好的电脑自学交流论坛! f& u( ]& I) w1 M8 d
4 e4 J+ K: `& P% s, b/ C2 Z9 B/ i$ w我爱电脑技术论坛e.ename = b.ename电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站4 C+ H( {8 u5 O$ E% Y
: h2 c. i! p& i) y1 j" q! V$ X我爱电脑技术论坛
5 l+ {0 s1 K. ~电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站这个例子要求优化器按顺序连接在SQL语句的FROM子句中指定的表,在FROM子句中的第一个表指定了驱动表。ordered提示通常被用来与其它的提示联合起来来保证采用正确的顺序连接多个表。它的用途更多的是在扭转连接表数在四个以上的数据仓库的查询方面。 打造最好的电脑自学交流论坛- C" e/ e+ z$ W( o2 _
我爱电脑技术论坛2 J7 d; S% R- n! R* `2 u1 v8 O1 x
电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站, F; O3 k9 ?/ E+ j$ g/ U
另外一个例子,下面的查询使用ordered提示按照指定的顺序来连接表:emp、dept、sal,最后是bonus。我通过指定emp到dept使用哈希连接和sal到bonus使用嵌套循环连接,来进一步精炼执行计划。 打造最好的电脑自学交流论坛: j( D2 n7 C A2 |6 l* A
1 _2 V; S" \( k; j4 b1 d
2 D% D0 A* d g. u6 n& [6 X打造最好的电脑自学交流论坛select /*+ ordered use_hash (emp, dept) use_nl (sal, bonus) */www.520diannao.com9 p9 B% A) G0 K# J
) z/ W' B1 N. j/ E我爱电脑技术论坛from
6 v2 P% o( N, z0 ywww.520diannao.com 我爱电脑技术社区--打造最好的电脑技术自学交流平台% L, @& A; `1 p; L: \+ @% S' O
emp,我爱电脑技术社区--打造最好的电脑技术自学交流平台3 c9 O& u* [) k, k% F, {
& e6 B3 O* l* W, q$ z9 g; ]' [3 F
dept,www.520diannao.com9 R2 z9 G0 ] O8 J% H) G6 q
我爱电脑技术社区--打造最好的电脑技术自学交流平台) E' Q- A0 K6 t4 | l
sal,
1 Y$ J1 c# N5 A' L5 w; ^2 Iwww.520diannao.com
5 V. o) a; v# }* r) ^, g& l4 X打造最好的电脑自学交流论坛bonus我爱电脑技术社区--打造最好的电脑技术自学交流平台/ C4 N4 `/ U. K
www.520diannao.com1 G/ D3 Y" M5 o* D: V" V5 y7 L$ w
where .
9 o4 p+ Y+ T* l0 D9 W" B m: P _电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站 www.520diannao.com( q. B) P; h( S: I
* S5 X& O% z' V) k5 ]+ A# s我爱电脑技术论坛电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站8 |) O1 ]- f4 H3 b5 m$ m
建议:
( B& W9 n5 P% [7 \我爱电脑技术社区--打造最好的电脑技术自学交流平台
/ W4 Y. ?: a2 K9 U$ A; Y6 D电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站
- n6 Q9 x: [, ?, e! H5 {3 f打造最好的电脑自学交流论坛实际上,更有效率的做法是在产品环境中减小optimizer_max_permutations参数的大小,并且总是使用稳定的优化计划或存储轮廓来防止出现耗时的含有大量连接的查询。一旦找到最佳的连接顺序,您就可以通过增加ordered提示到当前的查询中,并保存它的存储轮廓,来为这些表手工指定连接顺序,从而使其持久化。 我爱电脑技术社区--打造最好的电脑技术自学交流平台& ]( {8 _6 O- w. f
, f- C& H3 B) ewww.520diannao.com
+ v9 M# W" D2 lwww.520diannao.com当你打算使用优化器来稳定计划,则可以照下面的方法使执行计划持久化,临时将optimizer_search_limit设置为查询中的表的数目,从而允许优化器考虑所有可能的连接顺序。然后,通过重新编排WHERE子句中表的名字,并使用ordered提示,与存储轮廓一起使变更持久化,来调整查询。在查询中包含四个以上的表时,ordered提示和存储轮廓将排除耗时的评估SQL连接顺序解析的任务,从而提高查询的速度。 www.520diannao.com: z% a( }3 A) _
: S/ `) B; q L8 _
电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站, Z+ U3 L! ^; [+ F/ f) j- O
一旦检测到最佳的连接顺序,我们就可以使用ordered提示来重载optimizer_search_limit和optimizer_max_permutations参数。ordered提示要求表按照它们出现在FROM子句中的顺序进行连接,所以优化器没有加入描述。 % U: b% W! q1 g$ Y+ t! ?
打造最好的电脑自学交流论坛- z k& Y. c" h) w& r2 H
电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站1 Z( x9 B( G8 Z/ N+ ?
作为一个Oracle专业人员,你应该知道在SQL语句第一次进入库缓存时可能存在重大的启动延迟。但是聪明的Oracle DBA和开发人员能够改变表的搜索限制参数或者使用ordered提示来手工指定表的连接顺序,从而显著地减少优化和执行新查询所需的时间。