oracle复合索引第一个字段,复合索引的先决使用条件 - stacktestor的个人空间 - 51Testing软件测试网 51Testing软件测试网-软件测试人的精神家园...
背景:51Testing軟件測試網(wǎng)]k2u4q[F
今天,接到一個(gè)項(xiàng)目的項(xiàng)目經(jīng)理電話,告之說生產(chǎn)環(huán)境有幾個(gè)查詢超級(jí)慢,就是查詢單張表的數(shù)據(jù),查詢條件也很簡單,但是加了索引以后并沒有走索引,依然還是走的全表掃描。
UQZ5V!z.oh0聽到該問題描述,我開始浮想聯(lián)翩,統(tǒng)計(jì)信息太舊?存在隱式轉(zhuǎn)換?索引樹傾斜度太高,導(dǎo)致oracle認(rèn)為走索引的成本更高?
%|vE#z2B/e1?m0帶著各種可能的原因猜想,火速趕到了現(xiàn)場,發(fā)現(xiàn)原來都是我想多了。不走索引單純是建立的索引不合理,查詢條件是多個(gè)字段,應(yīng)該建立復(fù)合索引,現(xiàn)場維護(hù)人員只對(duì)其中單個(gè)字段建立了索引,ORACLE認(rèn)為不如走全表掃描開銷小,所以沒走索引。
[3FQF
eg0汗~~~~~~
[5M:LB4`~0添加索引的時(shí)候發(fā)現(xiàn),幾個(gè)不同的查詢,查詢條件字段都一樣,但是寫的順序卻不一樣(開發(fā)寫SQL太隨意了!!!!字段一樣,順序也寫成一樣啊!!!!!!!),結(jié)果先劇透一下,同樣也是可以走索引的。而由此聯(lián)想到些問題,于是在解決完效率問題后,在個(gè)人環(huán)境上做了一個(gè)驗(yàn)證。51Testing軟件測試網(wǎng)$vc-T zg
這個(gè)就是完整的背景。
!RYG-O:F*]I ^M051Testing軟件測試網(wǎng)&O@8saHK
---------------------------------------------------51Testing軟件測試網(wǎng)?7d]7g0T;M
驗(yàn)證內(nèi)容:51Testing軟件測試網(wǎng)~r zvrz#Maq
ORACLE 11GR2 復(fù)合索引的使用條件。51Testing軟件測試網(wǎng)f VWMT.h6h6p,f
前提條件:
A6GeAk8k!aX0創(chuàng)建一張表,并對(duì)字段A、B建立組合索引,順序?yàn)閕ndex(A、B);
/?SHYj}Un(i0測試場景:51Testing軟件測試網(wǎng)oB g-e`\}&C針對(duì)以下6個(gè)場景進(jìn)行測試:51Testing軟件測試網(wǎng)7xX^2sx5p(o1、查詢條件為:A='XXX' and B='YYY';? 順序完全一致的情況;
!~"{Y*D\7a,w(F:M1E02、查詢條件為:B='YYY' and A='XXX';? 順序不一致的情況;51Testing軟件測試網(wǎng)&@*{q9kE5dnM
3、查詢條件為:A='XXX';????????????? 單個(gè)字段且為復(fù)合索引前導(dǎo)列的情況;
4Ca"BSDw#f04、查詢條件為:B='YYY';????????????? 單個(gè)字段且不是復(fù)合索引前導(dǎo)列的情況;
@.ch-N?(v%m05、查詢條件為:C='ZZZ' and A='XXX';? 查詢條件既包含其它字段,也包含復(fù)合索引前導(dǎo)列的情況;
#cYCl!XJ06、查詢條件為:C='ZZZ' and B='YYY';? 查詢條件既包含其它字段,也包含復(fù)合索引非前導(dǎo)列字段的情況;
W4CBQ9I4f07、查詢條件為:C='ZZZ' and A='XXX' and B='YYY';? 查詢條件除復(fù)核索引字段外還包括其它字段,且索引外字段在第一位;
jWE)TA4}051Testing軟件測試網(wǎng)1_Yv&|f,m/R,B
---------------------------------------------------
,L
O2O'A)]|h2p0執(zhí)行過程:51Testing軟件測試網(wǎng)f?s,Ow2w;n
51Testing軟件測試網(wǎng)i8n5T(pACV
創(chuàng)建測試數(shù)據(jù):
6r9Lre6Kh+f%P0create table test_index_demo(recid? RAW(16) not null,customer_id RAW(16) not null,product_id? RAW(16) not null)
!s-Q8j
VB$B3G0create unique index index_test on test_index_demo (CUSTOMER_ID, PRODUCT_ID)
+Z^&Lz.d(@-fF%oQ)u0根據(jù)查詢字段做笛卡爾積準(zhǔn)備了將近3000萬數(shù)據(jù);
FI_d.OJ(M$fk0exec dbms_stats.gather_index_stats(ownname => 'gboss',indname =>'test_index_demo');51Testing軟件測試網(wǎng)GC$b$O0`9G
51Testing軟件測試網(wǎng)9]+rt,Qg7qb ^
分別針對(duì)每個(gè)場景進(jìn)行測試,查看執(zhí)行計(jì)劃如下:51Testing軟件測試網(wǎng)S+l.X/gU
場景一:51Testing軟件測試網(wǎng)? f"~8}_'U:i
select * from TEST_INDEX_DEMO T WHERE T.CUSTOMER_ID=HEXTORAW('01540EAA1D8E690099261D41257815D9') AND T.PRODUCT_ID=HEXTORAW('01540EAB83EC6900E30EAD424661D792');51Testing軟件測試網(wǎng)wSi9AwS
51Testing軟件測試網(wǎng)(cZnB0|-Z9nb
此處是走索引的,符合預(yù)期;
[+YV.OmCq&i0
:pSfc!TR4Vo#z0場景二:
Vp8T0fuZ0select * from TEST_INDEX_DEMO T WHERE
T.PRODUCT_ID=HEXTORAW('01540EAB83EC6900E30EAD424661D792') AND T.CUSTOMER_ID=HEXTORAW('01540EAA1D8E690099261D41257815D9');51Testing軟件測試網(wǎng)aT[!l;D
#tlIf4e:Sc0此處可以看到ORACLE的優(yōu)化器實(shí)際上把查詢條件的順序進(jìn)行了調(diào)整,所以同樣走了索引,符合預(yù)期;
$HPydx.A3^/r0
B3lHR(klK.A"|c0場景三:
es(|_i:EU4["\0select * from TEST_INDEX_DEMO T WHERE
T.CUSTOMER_ID=HEXTORAW('01540EAA1D8E690099261D41257815D9');51Testing軟件測試網(wǎng)8J U6N]+dSI^@|D
51Testing軟件測試網(wǎng)h5D#VBN+\D%}+t
此處因?yàn)椴樵儣l件為復(fù)合索引的前導(dǎo)列,所以走了索引,符合預(yù)期;
En6P-}/NR6D k~E7u051Testing軟件測試網(wǎng)ej.^ZXFVD
場景四:51Testing軟件測試網(wǎng)k*d!J.xVLe3If
select * from TEST_INDEX_DEMO T WHERE
T.PRODUCT_ID=HEXTORAW('01540EAB83EC6900E30EAD424661D792');51Testing軟件測試網(wǎng)8])M(g#d,YC0@
51Testing軟件測試網(wǎng) i.DYE dkc9`
此處沒有走索引,走的全表掃描,我原本以為即便不是復(fù)合索引的前導(dǎo)列,也會(huì)走索引的,看來我原來的認(rèn)識(shí)是錯(cuò)誤的。51Testing軟件測試網(wǎng)uI;v1sxpG
針對(duì)這個(gè)我特意臨時(shí)添加了index(B、A)驗(yàn)證了一下,是因?yàn)椴樵儣l件字段不是復(fù)合索引前導(dǎo)列導(dǎo)致,還是因?yàn)槌鲇谄渌矫娴某杀究紤],測試發(fā)現(xiàn),添加了index(B、A)順序的索引后,該SQL就可以走索引了,所以應(yīng)該可以認(rèn)為是查詢條件字段不是復(fù)合索引前導(dǎo)列導(dǎo)致的。51Testing軟件測試網(wǎng)QB_iF
j*T-P3D5d`#W y0場景五:
Tt"@Y/~+]9|l0select * from TEST_INDEX_DEMO T WHERE51Testing軟件測試網(wǎng)e0ONmxDEiI
T.RECID=HEXTORAW('01540ED5DA7069465FB7E42D07EDC156') AND T.CUSTOMER_ID=HEXTORAW('01540EAA1D8E690099261D41257815D9');
)GP1eeh2W051Testing軟件測試網(wǎng)]UY4p
x,q#\
ORACLE優(yōu)化器并沒有調(diào)整查詢條件字段的順序,但是依然走了索引。走索引是符合預(yù)期的,但是我原本以后應(yīng)該會(huì)改變字段順序的,這塊我有點(diǎn)不太理解,如果有看到這篇日志的大牛請(qǐng)幫忙解惑一下,謝謝。51Testing軟件測試網(wǎng)q*|q\([Yu.C
51Testing軟件測試網(wǎng)NrEx5n6V_/iyR
場景六:51Testing軟件測試網(wǎng)&B`e3@h4^(HI
select * from TEST_INDEX_DEMO T WHERE51Testing軟件測試網(wǎng)TI*Fua"x|E'm]$T
T.RECID=HEXTORAW('01540ED5DA7A69461D878CAE1CED2B7E') AND T.PRODUCT_ID=HEXTORAW('01540EAB83EC6900E30EAD424661D792');
jTR;R+t^;C051Testing軟件測試網(wǎng)+?!S2F{P
此處沒有走索引,倒是符合預(yù)期,汗~~~~
X0T\~D7y0
!~%J4LU4w+U&E:j0場景七:51Testing軟件測試網(wǎng),m0B+OU.I2J7vV
select * from TEST_INDEX_DEMO T WHERE
pTyAn0T.RECID=HEXTORAW('01540ED5DA7A69461D878CAE1CED2B7E') AND T.CUSTOMER_ID=HEXTORAW('01540EAA1D8E690099261D41257815D9') AND
T.PRODUCT_ID=HEXTORAW('01540EAB83EC6900E30EAD424661D792');
2O)V3Dbek8V2LW0
6AE-i2P
E9D%K0此處走索引了,結(jié)果倒是符合預(yù)期。51Testing軟件測試網(wǎng)5E&V+F:_{{Y
C,ZP2k1kNl@'kbw0----------------------------------------------------
EG(h`
x[i0結(jié)果對(duì)比及結(jié)論:51Testing軟件測試網(wǎng)2z2tm}(e.s9?mo所以經(jīng)此對(duì)比,我的結(jié)論是:
2b{7oRT%a01、查詢條件字段與復(fù)合索引字段一致的,無論順序如何,ORACLE優(yōu)化器會(huì)自動(dòng)調(diào)整順序,結(jié)論是會(huì)走索引;
(A*rO,v!A02、查詢條件字段與復(fù)合索引字段不一致,查詢條件字段包含復(fù)合索引前導(dǎo)列的,可以走索引;不包含索引前導(dǎo)列,則不走索引;
oo-Wp8j0--------------------------51Testing軟件測試網(wǎng),z
Y z#k:W3@
所以,由此結(jié)論可以看出,在設(shè)計(jì)查詢的時(shí)候,還是應(yīng)該要求開發(fā)在組織SQL的時(shí)候?qū)τ诘谝粋€(gè)查詢條件該用哪個(gè)字段還是需要綜合考慮系統(tǒng)所有查詢來進(jìn)行設(shè)計(jì)一下的。
:zZ;} vhs}%B0
總結(jié)
以上是生活随笔為你收集整理的oracle复合索引第一个字段,复合索引的先决使用条件 - stacktestor的个人空间 - 51Testing软件测试网 51Testing软件测试网-软件测试人的精神家园...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 29 伪造ICMP数据包的IP层
- 下一篇: 115网盘资源下载到群晖