回答

收藏

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

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

在同一查询中应用条件 之前,应先* 应用OracleSTART WITH ... CONNECT BY子句。因此,WHERE约束将无助于优化。
2 f; T; I% k; u  ?  w' ]% }
*WHERE``CONNECT BY
  v! m# I  W4 ^; O, A( e  B1 `例如,以下查询可能会执行全表扫描(忽略的选择性dept_id):
. m" F9 ~0 M9 W$ N, c: BSELECT * FROM employees
6 ?, r7 K% x0 T. mWHERE dept_id = 'SALE'
& u: a: S% d$ ~START WITH manager_id is null
6 t9 w% e3 m. _, OCONNECT BY PRIOR employee_id = manager_id
* H( U9 z$ K  Q: U我尝试通过两种方法来提高性能:# H  u3 }1 a, Z  R/ V3 d
查询A:2 G/ [$ F& s: X7 i' R
SELECT * FROM employees
+ e: l5 F) y* p8 s* \START WITH manager_id is null AND dept_id = 'SALE'9 v. g- B: \9 b
CONNECT BY PRIOR employee_id = manager_id8 s& h" |! K! W! M1 r3 N" l/ v6 R
查询B:" V1 J+ ]" |. a  j- W1 ]% m# P
SELECT * FROM (
4 b5 n$ B# a/ f# l0 X- x- J, l               SELECT * FROM employees
2 k$ [) r; U5 b                WHERE dept_id = 'SALE'
) ]8 W" @4 a* x( y, d: V* V( o/ v              )4 U  A7 D5 M0 |" N( K
START WITH manager_id is null
9 v# e5 [6 Q9 NCONNECT BY PRIOR employee_id = manager_id
8 _# w, V7 @+ ~尽管这两个查询的性能都比原始查询好很多,但是在Oracle 10g第2版中,查询B的性能却比A好得多。0 b8 ~) }1 I0 x( p. d. m6 ?
您是否有类似的性能优化来处理关于CONNECT BY和WHERE子句?您如何解释查询B比查询A做得更好?
6 {2 R, T% j7 v, l, R                , B, k( S0 B5 [) ?8 ]
解决方案:4 c1 \! w+ `3 K% |6 W8 N6 ?: N
                4 ]7 Q) I7 \. \& [: ?" I

: m% b. m' W" |  _1 E0 y
  D8 y' o" ~) @5 u0 V3 Y( R                查询A说从销售部门的经理开始,然后得到他们的所有员工。Oracle不“知道”查询返回的 所有 员工都将在销售部门,因此,在执行CONNECT4 R2 |5 }1 x/ a0 \) Q8 u6 D1 V
BY之前,它无法使用该信息来减少要使用的数据集。
5 J5 d6 M7 [+ ~: H3 T% T查询B 显式 减少了要处理的数据集,仅针对Sales中的那些员工,然后Oracle在执行CONNECT BY之前可以执行此操作。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则