回答

收藏

与WHERE子句一起使用时优化Oracle CONNECT BY

技术问答 技术问答 268 人阅读 | 0 人回复 | 2023-09-14

在同一查询中应用条件 之前,应先* 应用OracleSTART WITH ... CONNECT BY子句。因此,WHERE约束将无助于优化。
: R' c! J+ e7 d  v8 X' M& D4 w
*WHERE``CONNECT BY
3 p8 G( a7 p& ]5 c例如,以下查询可能会执行全表扫描(忽略的选择性dept_id):
0 V9 ~7 _; x5 X  ISELECT * FROM employees
' o2 ~' Y& K& D# c- l/ ]WHERE dept_id = 'SALE'
2 G' ^" k  r8 d$ g) c0 X! @START WITH manager_id is null* E/ h4 H: y9 |+ M& i! s& M8 G- q
CONNECT BY PRIOR employee_id = manager_id1 {. W( Z7 A# d& O3 Q
我尝试通过两种方法来提高性能:- P5 ~& R& z1 _5 ]
查询A:7 x# ?  }+ d6 |! o1 U" a
SELECT * FROM employees
1 s; M; `  M, R2 P, sSTART WITH manager_id is null AND dept_id = 'SALE'
0 [; z' N: ]- U# K- N( _CONNECT BY PRIOR employee_id = manager_id
0 L  ^, k& d' H, J; A. b4 z查询B:
0 r% M' r1 R/ Y! bSELECT * FROM (! {" t2 R: h, r* T# J( O" d
               SELECT * FROM employees + a6 ^8 M/ m9 I* z7 A6 v
                WHERE dept_id = 'SALE'
. A/ v- O& ]8 O! L              )
& R$ }9 {# j+ ^9 Q8 c' |7 @START WITH manager_id is null% o8 f( Z. J6 S7 l
CONNECT BY PRIOR employee_id = manager_id' F% |+ @) P. z6 b  W; W% [+ B. q
尽管这两个查询的性能都比原始查询好很多,但是在Oracle 10g第2版中,查询B的性能却比A好得多。$ @0 F9 T4 [3 ]2 h* c4 Y# G2 k. t& A3 s
您是否有类似的性能优化来处理关于CONNECT BY和WHERE子句?您如何解释查询B比查询A做得更好?' I' o! `$ x$ `# [& ~, y
               
, @( b6 t$ h& I5 x3 u9 {: h: b解决方案:1 y/ ^) C7 E2 @5 I6 L  g
               
: G( p! s2 I1 T/ b) V6 A( V5 h" ^! k& U- M# L- ~* X$ n# s

+ g& W1 s3 @  K0 R4 U$ m2 I4 `, J5 k                查询A说从销售部门的经理开始,然后得到他们的所有员工。Oracle不“知道”查询返回的 所有 员工都将在销售部门,因此,在执行CONNECT
2 m. i; [. y5 OBY之前,它无法使用该信息来减少要使用的数据集。
* O5 O) \4 o2 n7 Z# D查询B 显式 减少了要处理的数据集,仅针对Sales中的那些员工,然后Oracle在执行CONNECT BY之前可以执行此操作。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则