与WHERE子句一起使用时优化Oracle CONNECT BY
技术问答
369 人阅读
|
0 人回复
|
2023-09-14
|
在同一查询中应用条件 之前,应先* 应用OracleSTART WITH ... CONNECT BY子句。因此,WHERE约束将无助于优化。
/ ^6 X) o4 y, K0 Z' K! X*WHERE``CONNECT BY
4 b, m6 v# F7 i% W" N* M2 s例如,以下查询可能会执行全表扫描(忽略的选择性dept_id):6 @+ V& S' _. C( X' C' }8 u
SELECT * FROM employees
1 s, ]& U% d" K7 jWHERE dept_id = 'SALE'! s5 L8 |* X- M% U! V
START WITH manager_id is null
1 j/ s5 ?' Z+ X' D+ Y6 \2 T. @CONNECT BY PRIOR employee_id = manager_id
" ^* _# \, y) C" L/ _* R6 A我尝试通过两种方法来提高性能:
D( K/ [7 j% S3 g0 P6 l查询A:
1 M8 |% {+ I! x5 A) QSELECT * FROM employees
( Y8 S+ f: T- a+ M- JSTART WITH manager_id is null AND dept_id = 'SALE', W/ x# U) S$ f; I8 I
CONNECT BY PRIOR employee_id = manager_id
d8 @- c- r% k- E5 C" z7 \. D: v查询B:3 q! E! N; P4 L7 B7 D5 [
SELECT * FROM (! x* j' T' a- i8 r6 o
SELECT * FROM employees : U k$ t- G0 n: ?
WHERE dept_id = 'SALE'
! B& h* Z' A. ^# O/ Z )6 i& h* R' j2 l# r9 c3 T, a
START WITH manager_id is null9 ?2 R$ M- i, a3 W0 m2 P
CONNECT BY PRIOR employee_id = manager_id: S2 a2 X; ]* G5 m5 ?
尽管这两个查询的性能都比原始查询好很多,但是在Oracle 10g第2版中,查询B的性能却比A好得多。
5 M- t8 f# D" c- E1 g. I您是否有类似的性能优化来处理关于CONNECT BY和WHERE子句?您如何解释查询B比查询A做得更好? r+ e3 u- k' v/ V
P) U2 F. C8 C+ W( A, l5 U解决方案:) F1 j$ @ Q, a7 s4 M0 n* [" ~4 g
5 U6 F# h, c Y
! e6 B0 i. T7 m) q* b* V
4 O$ I- m( _: U. ]$ ~ 查询A说从销售部门的经理开始,然后得到他们的所有员工。Oracle不“知道”查询返回的 所有 员工都将在销售部门,因此,在执行CONNECT
- j4 L8 `& t6 \ r9 aBY之前,它无法使用该信息来减少要使用的数据集。4 N( F, |% G$ j3 V
查询B 显式 减少了要处理的数据集,仅针对Sales中的那些员工,然后Oracle在执行CONNECT BY之前可以执行此操作。 |
|
|
|
|
|