jdbc驅(qū)動(dòng)深度優(yōu)化_第1頁(yè)
jdbc驅(qū)動(dòng)深度優(yōu)化_第2頁(yè)
jdbc驅(qū)動(dòng)深度優(yōu)化_第3頁(yè)
jdbc驅(qū)動(dòng)深度優(yōu)化_第4頁(yè)
jdbc驅(qū)動(dòng)深度優(yōu)化_第5頁(yè)
已閱讀5頁(yè),還剩14頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

JDBC驅(qū)動(dòng)深度優(yōu)化引自支付寶周倉(cāng)分享什么是綁定變量?

在Oracle中如果實(shí)現(xiàn)實(shí)現(xiàn)系統(tǒng)緩慢甚至停頓,完全可以不使用綁定變量輕松實(shí)現(xiàn),比如想查詢一下熊大的易極付帳號(hào)里有多少錢,可以用以下兩種方式進(jìn)行查詢。select*fromacctrans_accountwhereaccount_no=‘熊大’;select*fromacctrans_accountwhereaccount_no

=:accno;Oracle綁定變量第一種情況下,DB每次都會(huì)該查詢語(yǔ)句進(jìn)行語(yǔ)法檢查、語(yǔ)意分析、生存執(zhí)行計(jì)劃、計(jì)劃優(yōu)化,這里我們稱之為硬解析。第二種情況下,DB只會(huì)進(jìn)行一次編譯,并將查詢計(jì)劃發(fā)放入共享池,以便后續(xù)可以重用這個(gè)查詢計(jì)劃,這里我們稱之為軟解析。在使用硬解析過(guò)程中oracle為了保證共享池中數(shù)據(jù)結(jié)構(gòu)不被串改和臟讀,會(huì)長(zhǎng)時(shí)間的使用串行處理,那么硬解析的數(shù)量越多,DB的性能下降將越快。Oracle軟硬解析訪問(wèn)數(shù)據(jù)庫(kù)的兩種方式A.createStatement() Statementstmt=conn.createStatement();

result=stmt.executeQuery(sql+"1");B.preparedStatement()

Stringv_sql='selectnamefromtable_awhereid=?'; stmt=conn.prepareStatement(v_sql);

stmt.setString(1,v_id);//為綁定變量賦值

stmt.executeQuery();相信各種各樣的教科書都會(huì)告訴大家B方案才是最合適的,當(dāng)然一般的理由都是sql注入的問(wèn)題。天生支持綁定變量的JDBC前面提到的共享池是隸屬與SGA的,將執(zhí)行計(jì)劃的定義信息緩存在了SGA中的共享池,其實(shí)Oracle可以做的還不止這一點(diǎn),它將用于返回給應(yīng)用的可執(zhí)行對(duì)象游標(biāo)將放入在PGA中進(jìn)行緩存,在使用階段,只需要填充參數(shù),分配內(nèi)存即可,不象在共享池中的緩存需要語(yǔ)法檢查、語(yǔ)意分析、創(chuàng)建游標(biāo)等動(dòng)作。以下為PGA緩存配置參數(shù)。1.session_cached_cursors(LRU)服務(wù)端(ps.close會(huì)進(jìn)入緩存,默認(rèn)為20)2.hold_cursor=YESandRELEASE_CURSOR=NO(默認(rèn)不啟用)PGA與SGA緩存Implicitstatementcache是oraclejdbc驅(qū)動(dòng)的一個(gè)緩存方案,它和很多對(duì)象池方案一樣都選擇了淘汰算法(LRU)。啟用代碼:OracleConnectionconn.setImplicitCachingEnabled(true);conn.setStatementCacheSize(10);OracleJDBC驅(qū)動(dòng)PS緩存由于JDBC驅(qū)動(dòng)并沒(méi)有定義緩存PSAPI,所以多數(shù)時(shí)候數(shù)據(jù)源都會(huì)提供自己的語(yǔ)句緩存方案,例如:jboss提供的publicclassPreparedStatementCacheextendsLRUCachePolicy緩存實(shí)現(xiàn),它同樣使用LRU淘汰算法,然后,有一些數(shù)據(jù)源例如druid就提供了特定數(shù)據(jù)庫(kù)的pscache支持,它oracle的配置如下<propertyname="poolPreparedStatements"value="true"/>

<propertyname="maxPoolPreparedStatementPerConnectionSize"value="20"/>數(shù)據(jù)源層的PS緩存創(chuàng)建一個(gè)PS對(duì)象是具有消耗的,即便各級(jí)都存在緩存,但應(yīng)用至數(shù)據(jù)庫(kù)之間的交付仍然會(huì)有一定的網(wǎng)絡(luò)負(fù)擔(dān)存在。在選擇應(yīng)用層緩存的時(shí)候,應(yīng)當(dāng)盡量選擇jdbc驅(qū)動(dòng)提供的緩存方案,因?yàn)镺racle更清楚JDBC中PreparedStatement的內(nèi)部結(jié)構(gòu)。因此,它可以管理該結(jié)構(gòu),以獲得最佳性能。特別是它可以管理的buffer驅(qū)動(dòng)程序的不同版本提供了不同的方式。緩存的注意事項(xiàng)每個(gè)preparedstatment對(duì)象提供兩個(gè)buffer緩沖區(qū),一個(gè)是byte[],另一個(gè)是char[],字符數(shù)組類型用于存放char,nchar,varchar2數(shù)據(jù)類型,字節(jié)數(shù)組則用于存放其他數(shù)據(jù)類型(BLOB、CLOB采用了其他方案,這里就不區(qū)糾結(jié)了),具體計(jì)算公式如下:rowSize和table中定義字段大小接近,還需附加column約兩個(gè)字節(jié),如:createtable(identitynumber(17),contentvarchar2(20));rowSize=17+2+20*2+2

java中char占用兩個(gè)字節(jié)OracleJDBC驅(qū)動(dòng)內(nèi)存緩沖區(qū)當(dāng)執(zhí)行一條sql語(yǔ)句的時(shí)候,將獲取一個(gè)可執(zhí)行對(duì)象游標(biāo),將申請(qǐng)兩個(gè)緩沖區(qū),這塊內(nèi)存區(qū)中存放的數(shù)據(jù)行數(shù)將由這個(gè)值決定,Oracle默認(rèn)該值為10,可以通過(guò)它對(duì)應(yīng)的api為ps.setFetchSize(int),那么完整的內(nèi)存計(jì)算公式為charsSize

=rowSize*fetchsizeFetchSize數(shù)據(jù)庫(kù) 連接方式 PSCACHE fetchsize 字段長(zhǎng)度 網(wǎng)絡(luò)距離 總記錄數(shù) 返回記錄 執(zhí)行時(shí)間(ms) ORACLE oci 支持 1 10000 15KM 300 0 1.5875 ORACLE oci 支持 50 10000 15KM 300 0 2.0468 ORACLE oci 支持 100 10000 15KM 300 0 2.6656 ORACLE oci 支持 1 10000 本地 300 0 0.1898 ORACLE oci 支持 50 10000 本地 300 0 0.3431 ORACLE oci 支持 100 10000 本地 300 0 1.2609 ORACLE thin 支持 1 10000 15KM 300 0 1.6344 ORACLE thin 支持 10 10000 15KM 300 0 1.6687 ORACLE thin 支持 100 10000 15KM 300 0

1.6266通過(guò)fetchsize提升性能不要忘了每個(gè)ps都會(huì)開(kāi)辟一個(gè)內(nèi)存區(qū),由于存在pscache,也就是說(shuō)連接池中的每個(gè)connection可能具備上百個(gè)ps,每個(gè)ps中的內(nèi)存緩沖區(qū)大小是由表中字段大小決定的,例如:每條紀(jì)錄定義:10k,fetchsize:50,pscache:100,連接池max值:30,

連接池個(gè)數(shù):2極端情況下,內(nèi)存占用會(huì)達(dá)到:2*10K*50*100*30*2=6GB不單如此由于占用內(nèi)存過(guò)高,還可能引起頻繁的fullgcFetchsize造成的OOM由于java語(yǔ)言本身要求對(duì)字節(jié)數(shù)組的填充必須使用0,在處理小的buffer狀況沒(méi)什么問(wèn)題,如果分配一個(gè)大buffer那么填充過(guò)程將成為最大的性能瓶頸。Oracle驅(qū)動(dòng)在每一次本版升級(jí)后都對(duì)內(nèi)存緩沖區(qū)管理進(jìn)行了調(diào)整,所以在選擇pscache的時(shí)候應(yīng)當(dāng)盡量直接選擇oracle本身提供的pscache方案。而通用的數(shù)據(jù)源語(yǔ)句cache在沒(méi)有特殊處理的情況下是不可能相比的。Pscache的抉擇Oracle10G驅(qū)動(dòng)當(dāng)一個(gè)PreparedStatement是第一次執(zhí)行,必要的byte[]和char[]buffer會(huì)被分配。就是這樣。buffer只有在PreparedStatement本身被釋放(freed)的時(shí)候才會(huì)被釋放(freed)。ImplicitStatementCache不會(huì)為管理buffer做任何事情。所有ImplicitStatementCache中緩存的PreparedStatements的持有著其分配的byte[]和char[]buffer準(zhǔn)備立即被重用Pscache的抉擇(2)Oracle10.2.0.4G驅(qū)動(dòng)10.2.0.4.0驅(qū)動(dòng)程序添加了一個(gè)連接屬性著手解決出現(xiàn)在初始10g驅(qū)動(dòng)程序的內(nèi)存管理問(wèn)題。此連接屬性采用一種一刀切的方式。如果設(shè)置,返回一個(gè)PreparedStatement到ImplicitStatementCache中的時(shí)候會(huì)釋放其中的buffer。Statement是從cache中取出時(shí),buffer會(huì)被重新分配。這個(gè)簡(jiǎn)單的方法大大地減少了內(nèi)存使用,但是犧牲了巨大的性能成本。如上所述,分配buffer是昂貴的。這個(gè)連接屬性就是oracle.jdbc.freeMemoryOnEnterImplicitCache它的值是一個(gè)boolean字符串,“true”或“false”。如果設(shè)為“true”,當(dāng)一個(gè)PreparedStatement返回cache時(shí),buffer會(huì)被釋放。如果設(shè)為“false”(默認(rèn)值也是“false”),buffer被保留,和最初的10g驅(qū)動(dòng)程序一樣。該屬性可以通過(guò)-D被設(shè)置為Systemproperty或作為調(diào)用getConnection方法時(shí)候的connectionproperty。請(qǐng)注意,設(shè)置freeMemoryOnEnterImplicitCache不會(huì)導(dǎo)致參數(shù)值buffer被釋放,它只會(huì)影響該行數(shù)據(jù)buffer。Pscache的抉擇(3)Oracle10.2.0.4G驅(qū)動(dòng)此版本實(shí)現(xiàn)兩個(gè)目標(biāo),最大限度地減少未內(nèi)存使用量和最小化分配buffer的成本。驅(qū)動(dòng)程序在每個(gè)連接內(nèi)部創(chuàng)建了一個(gè)buffer緩存(buffercache)。當(dāng)一個(gè)PreparedStatement返回到ImplicitStatementCache中的時(shí)候,它的buffer會(huì)被緩存到buffer緩存中。當(dāng)一個(gè)PreparedStatement是從ImplicitStatementCache中取出時(shí),buffer會(huì)也會(huì)同時(shí)從buffer緩存中取出。因此,ImplicitStatementCache中的PreparedStatement不再持有大的buffer,buffer會(huì)被多次重用而不是被多次創(chuàng)建。相比10g驅(qū)動(dòng)程序,不管有沒(méi)有freeMemoryOnEnterImplicitCache,都顯著地提升了驅(qū)動(dòng)程序的性能。Pscache的抉擇(4)OCI&THIN指標(biāo)10goci11gthin結(jié)論cpuUser3%-6%User2%-5%Usercpu會(huì)有較大下降。堆外內(nèi)存2.55-2.88g2.15g省了幾百塊堆內(nèi)內(nèi)存300M+200M省了一百塊服務(wù)響應(yīng)時(shí)間538.28ms467.38ms這個(gè)比較明顯,服務(wù)下降了70.9msDal層1.23ms0.98ms有點(diǎn)優(yōu)勢(shì)連接創(chuàng)建100ms(140)20ms(1000)瞬間爆發(fā)有優(yōu)勢(shì)TAF,MTS支持不支持ps.setQueryTImeout();防止查詢階段因?yàn)閽弑硪鸬穆樵儗?dǎo)致整個(gè)系統(tǒng)和DB處于阻塞狀態(tài)。設(shè)置之后timeout線程檢查超時(shí)并調(diào)用ps.cancel(),拋出sql

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論