回答

收藏

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

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

在同一查询中应用条件 之前,应先* 应用OracleSTART WITH ... CONNECT BY子句。因此,WHERE约束将无助于优化。# d: X: U- N0 `- \
*WHERE``CONNECT BY* v9 @0 B- C) s
例如,以下查询可能会执行全表扫描(忽略的选择性dept_id):
8 s% R+ \& k7 H* H) t- Q$ I7 \1 LSELECT * FROM employees
& d7 L7 ?, ^3 S6 e. r9 Y2 FWHERE dept_id = 'SALE'+ |7 ^7 g( n3 k) z: k
START WITH manager_id is null
3 I& R$ z. Z" RCONNECT BY PRIOR employee_id = manager_id  d9 s" o' O5 D/ d. q$ u/ }" K9 o
我尝试通过两种方法来提高性能:' E7 e, f! X2 @5 j0 p
查询A:) x( l' |; w& C- O* N  t
SELECT * FROM employees
4 n4 G* g5 e& k3 F! l8 q4 g/ v$ CSTART WITH manager_id is null AND dept_id = 'SALE'( L$ k( Q+ s# o. w  _
CONNECT BY PRIOR employee_id = manager_id
! }+ X5 k$ j; @& J% n2 H查询B:
8 `( ~, o0 ?7 ]0 V, GSELECT * FROM (
" x4 E9 u" D. L2 V, ?1 T9 K0 N- P               SELECT * FROM employees
* X; E, P  K4 d                WHERE dept_id = 'SALE'
  l: Z" ?& R5 G5 w' a1 j: w9 @% k) g              )
7 D! R  Y5 N; k# a4 C8 BSTART WITH manager_id is null5 B1 h" }  }5 ^
CONNECT BY PRIOR employee_id = manager_id
. X$ n/ G# O1 X( w: Y尽管这两个查询的性能都比原始查询好很多,但是在Oracle 10g第2版中,查询B的性能却比A好得多。
3 h/ f; X, l& e; v6 S/ j3 B! p您是否有类似的性能优化来处理关于CONNECT BY和WHERE子句?您如何解释查询B比查询A做得更好?
* q6 a6 ?0 G% p  J5 g- C  k               
8 X& \% ?* G% b& O$ G解决方案:4 g) h8 a4 x  w: @/ a2 c, g' b% C
               
5 ]0 l& O# t. u# B0 K
& c3 y' H9 D3 n, ~3 _1 b- z
+ x7 s+ y  S7 i# b; c                查询A说从销售部门的经理开始,然后得到他们的所有员工。Oracle不“知道”查询返回的 所有 员工都将在销售部门,因此,在执行CONNECT1 _6 ?! `; l( i5 \% i- c$ }' d: H
BY之前,它无法使用该信息来减少要使用的数据集。
) D0 J; w) Y4 V% _查询B 显式 减少了要处理的数据集,仅针对Sales中的那些员工,然后Oracle在执行CONNECT BY之前可以执行此操作。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则