|
所以我有一个查询,在SELECT中需要一堆CASE语句。这不是原始的设计,而是折衷的一部分。
; a- f" t0 b% G2 p9 E0 g因此查询看起来像这样:! _9 E2 z) }2 Q! O i
SELECT6 B3 U8 s- H! b3 Z& G% f
CONT.TABLE.FINC_ACCT_NM,
b4 _0 [3 F. t! l) Y# P. Y: Z CONT.TABLE.FINC_ACCT_ID,
5 J+ A. j3 X! B& o! m CONT.TABLE.CURR_END_OF_PERD_ACTL_VAL,
2 ]5 ~5 Z1 [& W9 n2 A7 H. g CONT.TABLE.PREV_END_OF_PERD_ACTL_VAL,; S2 j7 j0 z9 H& l
CONT.TABLE.VARNC_PLAN_VAL,
+ p4 [! C0 R& m# f5 o1 e CONT.TABLE.OUTLOOK_BDGT_PLAN_VAL,+ S E- k! N! k! o% k
CONT.TABLE.PERD_END_RPT_DT,) c0 }4 h H4 e& w# Q3 Q
CONT.TABLE.PLAN_VERS_NM,
0 h8 J( G C% R3 a* i, e; { CONT.TABLE.FRMT_ACTL_CD,1 j) q0 A3 f3 E
CONT.TABLE.FRMT_PLAN_CD,
( }: x) {0 }- b9 C V% ?5 i( K CONT.TABLE.RPT_PERD_TYPE_CD,0 w9 H' k# O' t/ C
CASE
$ B8 r* \& a9 {' W% Y WHEN ( CONT.TABLE.FINC_ACCT_ID )= 'XXXX' and ( CONT.TABLE.BAL_TYPE_CD ) = 'EOP' then ' Net Interest Income' / Y3 H& ^& z# K/ m% S# v. y
WHEN ( CONT.TABLE.FINC_ACCT_ID )= 'XXXX' and ( CONT.TABLE.BAL_TYPE_CD ) = 'EOP' then ' Non Interest Income'
# k, Y% h) E: f$ g WHEN ( CONT.TABLE.FINC_ACCT_ID )= 'XXXX' and ( CONT.TABLE.BAL_TYPE_CD ) = 'EOP' then 'Non-Interest Expense'
- v* U, E) C+ N% p1 H, V* B WHEN ( CONT.TABLE.FINC_ACCT_ID )= 'XXXX' and ( CONT.TABLE.BAL_TYPE_CD ) = 'EOP' then ' Total Marketing Expense'% S! a' a/ ^; K% y4 }; ?6 O
WHEN ( CONT.TABLE.FINC_ACCT_ID )= 'XXXX' and ( CONT.TABLE.BAL_TYPE_CD ) = 'EOP' then ' Total Operating Expense': C/ e( @ @' [. K
WHEN ( CONT.TABLE.FINC_ACCT_ID )= 'XXXX' and ( CONT.TABLE.BAL_TYPE_CD ) = 'EOP' then 'Pre-Provision Earnings (before tax)'
3 P) l/ w2 P0 J, \0 | WHEN ( CONT.TABLE.FINC_ACCT_ID )= 'XXXX' and ( CONT.TABLE.BAL_TYPE_CD ) = 'EOP' then ' Net Charge-offs'
! c3 v8 H8 J" A) b, I$ \8 p+ q# p WHEN ( CONT.TABLE.FINC_ACCT_ID )= 'XXXX' and ( CONT.TABLE.BAL_TYPE_CD ) = 'EOP' then ' Other'# p- w( Y- D A
WHEN ( CONT.TABLE.FINC_ACCT_ID )= 'XXXX' and ( CONT.TABLE.BAL_TYPE_CD ) = 'EOP' then ' Allowance Build (Release)'5 d( p% N0 o2 u j+ c# Y
WHEN ( CONT.TABLE.FINC_ACCT_ID )= 'XXXX' and ( CONT.TABLE.BAL_TYPE_CD ) = 'EOP' then 'Provision Expense'$ ?# H. B+ }$ j$ g- @ R9 [& S6 p
WHEN ( CONT.TABLE.FINC_ACCT_ID )= 'XXXX' and ( CONT.TABLE.BAL_TYPE_CD ) = 'EOP' then 'Pretax Income'* `" Y( e1 c* v2 {) v& ?/ e6 w
WHEN ( CONT.TABLE.FINC_ACCT_ID )= 'XXXX' and ( CONT.TABLE.BAL_TYPE_CD ) = 'EOP' then 'Tax Expense'
8 r2 f0 U3 j2 H% G WHEN ( CONT.TABLE.FINC_ACCT_ID )= 'XXXX' and ( CONT.TABLE.BAL_TYPE_CD ) = 'EOP' then 'NIAT'5 u* W" \0 L- i5 O+ M- u
WHEN ( CONT.TABLE.FINC_ACCT_ID )= 'XXXX' and ( CONT.TABLE.BAL_TYPE_CD ) = 'EOP' then 'EPS'! i: p6 z; W, S
WHEN ( CONT.TABLE.FINC_ACCT_ID )= 'XXXX' and ( CONT.TABLE.BAL_TYPE_CD ) = 'EOP' then 'Ending Loans - HFI'& i; T7 `# z, |. _8 D
WHEN ( CONT.TABLE.FINC_ACCT_ID )= 'XXXX' and ( CONT.TABLE.BAL_TYPE_CD ) = 'avg' then 'Average Loans - HFI'& N. g% k0 t+ s5 {, f3 h# i
WHEN ( CONT.TABLE.FINC_ACCT_ID )= 'XXXX' and ( CONT.TABLE.BAL_TYPE_CD ) = 'avg' then 'Average Earning Assets'% ?* c+ g; A* y! p: B
WHEN ( CONT.TABLE.FINC_ACCT_ID )= 'XXXX' and ( CONT.TABLE.BAL_TYPE_CD ) = 'EOP' then 'Ending Deposits'8 p# I# b! R: }! ?# O
WHEN ( CONT.TABLE.FINC_ACCT_ID )= 'XXXX' and ( CONT.TABLE.BAL_TYPE_CD ) = 'avg' then 'Average Deposits'/ M4 M0 N& V+ [. J# z
WHEN ( CONT.TABLE.FINC_ACCT_ID )= 'XXXX' and ( CONT.TABLE.BAL_TYPE_CD ) = 'EOP' then 'NIM on Loans'
5 f# _( u2 o) f. B/ p4 c WHEN ( CONT.TABLE.FINC_ACCT_ID )= 'XXXX' and ( CONT.TABLE.BAL_TYPE_CD ) = 'EOP' then 'Revenue Margin'
* {1 t! o; v% T. @: A WHEN ( CONT.TABLE.FINC_ACCT_ID )= 'AC579' and ( CONT.TABLE.BAL_TYPE_CD ) = 'EOP' then 'Charge off rate'
) P( m' J0 c6 G WHEN ( CONT.TABLE.FINC_ACCT_ID )= 'XXXX' and ( CONT.TABLE.BAL_TYPE_CD ) = 'EOP' then 'Efficiency ratio' }1 i0 I( z+ D7 c
WHEN ( CONT.TABLE.FINC_ACCT_ID )= 'XXXX' and ( CONT.TABLE.BAL_TYPE_CD ) = 'EOP' then 'ROA'
: t2 N4 h' B7 A- S2 e WHEN ( CONT.TABLE.FINC_ACCT_ID )= 'XXXX' and ( CONT.TABLE.BAL_TYPE_CD ) = 'EOP' then 'ROE', s* y6 I$ f9 ]! X7 \( u: H
WHEN ( CONT.TABLE.FINC_ACCT_ID )= 'XXXX' and ( CONT.TABLE.BAL_TYPE_CD ) = 'EOP' then 'Return on Allocated Capital (ROAC)'
/ C/ ]! i( ^- x, t
1 g I; |: S! p4 ^- X& x$ w2 E ELSE ( CONT.TABLE.FINC_ACCT_NM ) end- C' m, d" y* D0 v2 A1 b
FROM
' P( Z9 A7 k5 @ CONT.TABLE1 m+ S, H0 ]+ E) \8 B$ J2 W
WHERE
: ^1 e: p7 {" E$ O0 v9 h9 B (
5 f" S; e& S o" }+ j$ p+ y/ N, C* w (
% g6 `, t, a( q2 \" H$ G" g ( ( CONT.TABLE.PERD_END_RPT_DT ) = (
- R' f3 s. M- H1 U; {9 eSELECT Max(Perd_END_RPT_DT) 1 O. z' p! e* F4 B3 E
FROM CONT.TABLE; N+ _+ C8 `4 s; M3 H# \
Where VERS_NM='Actual'
- m1 `' m8 H0 P. Z, j0 O AND RPT_PERD_TYPE_CD = 'Q': Q9 ]% \ q0 |! W# @
AND DATA_VLDTN_IND='Y'9 L/ m& W7 f, A9 Q
)' W$ j# m' e5 @' f' L! h" |9 Z* ~9 Z
AND RPT_PERD_TYPE_CD = 'Q'
% ^ A: w# Z ?1 R AND DATA_VLDTN_IND='Y' )
0 z6 ?/ u, d( S. H7 N& A% F OR
" ^ W9 ], V: I8 b1 l ( ( CONT.TABLE.PERD_END_RPT_DT ) = (
+ D7 \& h3 K1 ESELECT Max(Perd_END_RPT_DT)
* F, w8 v& ~' n# D1 @# T oFROM CONT.TABLE6 ^4 c( G" G |; n' g
Where VERS_NM='Actual'
/ f" F% G/ {' ]0 k' J+ k AND RPT_PERD_TYPE_CD = 'M'
6 o$ m1 O! h u$ A. V- O AND DATA_VLDTN_IND='Y'
3 W7 l$ b* U, q7 G$ |3 U! k8 S8 @)
+ J* q2 F' j/ V4 i& m0 n0 R' C% u AND RPT_PERD_TYPE_CD = 'M'; p5 Z& t* B+ V+ v2 V0 _
AND DATA_VLDTN_IND='Y' )
% U: K Z& @# M+ n) D; H )5 B9 C z [. i4 m
AND& o1 g( h0 m7 r" Y
( ( CONT.TABLE.DATA_VLDTN_IND )='Y' )
) v5 D, \9 }2 ~; I! | AND
. d2 \# f5 d5 F5 Y ( ( CONT.TABLE.FINC_ACCT_ID )IN ('AC0006470','AC8000199','AC8002145','AC0006586','AC8000094') AND ( CONT.TABLE.DEPT_ID )='OR80637' )2 V$ A8 ?1 @ w" S, v u% l
)3 c) G1 t2 N2 F& m8 h& w
我的问题是,将所有这些CASE语句更改为直接列引用会对性能产生什么影响。7 m# m% P: H; B3 b
换句话说:如果我将每个CASE语句更改为一个列名,并从查询中删除了所有CASE语句,那么会对性能产生很大影响,为什么?6 `$ O' Q$ w& x, g( M# |# w I# _
我正在对此进行测试,因此我可以弄清楚性能是否受到影响,但是我对WHY的细节也同样感兴趣?(为什么的技术细节)
% d. ^6 O$ t7 `+ Q谢谢你的帮助!' q! c8 P0 E, Z
4 h% Z- t" L# N2 ] ~解决方案:/ B# n& \# L$ J! z4 Q. H5 o; W3 v
; |9 w( D ^2 ^8 I2 ^$ q
- W) l/ E- J0 ^# W; A0 y7 J7 V) E
! d6 X7 d' g' h 与WHERE子句中的联接相比,case语句的影响要小得多。
, Q* H* q; z5 K9 QSQL性能的主要驱动力是I / O -从磁盘读取数据。我认为它比行处理要重要两个数量级。这只是一种启发式方法,并不基于数据库上的特定测试。
: x8 x9 g+ ?) d7 j, o: I7 K m您正在执行自联接,这将需要大量的工作来读取表或进行大量的索引处理工作。& M9 v7 e3 E G1 t+ Q
另一方面,case语句变成了非常原始的硬件命令-+ p& R0 J* P z8 Q- y
equals,gotos等。数据驻留在最靠近处理器的内存中,因此它将进行压缩。您对case语句(例如like或子查询)没有任何幻想。我可以想象,如果删除语句中的大多数行,查询的速度将一样快。
0 ?3 r1 ^ V! C: j+ B如果您对性能有疑问,请在(VERS_NM,RPT_PERD_TYPE_CD,DATA_VLDTN_IND,Perd_END_RPT_DT)上添加索引。这个由四部分组成的索引应该使您能够获得最长时间,而无需在原始表上调用I
. c8 Y+ [* D. Y/ B/ O请求。 |
|