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