与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之前可以执行此操作。 |
|
|
|
|
|