国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
oracle11g新特性-緩存和連接池
緩存和連接池
探究如何使用 SQL 結(jié)果緩存、PL/SQL 功能緩存和客戶端緩存以及數(shù)據(jù)庫駐留連接池來改善性能。
下載 Oracle 數(shù)據(jù)庫 11g
SQL 結(jié)果緩存
訪問內(nèi)存比訪問硬盤快得多,在接下來幾年中,除非硬盤體系結(jié)構(gòu)有重大改進,不然這一情況很可能會持續(xù)。緩存這一將數(shù)據(jù)存儲于內(nèi)存而非硬盤中的過程由此應(yīng)運而生。緩存是 Oracle 數(shù)據(jù)庫體系結(jié)構(gòu)的一個基本原理,用戶從緩存而非數(shù)據(jù)庫所駐留的磁盤中獲取數(shù)據(jù)。
在相對較小的含靜態(tài)數(shù)據(jù)的表中,如 STATES、PRODUCT_CODES 等參考表,緩存的優(yōu)勢異乎尋常的明顯。但是,假設(shè)有一個存儲公司客戶的大型表 CUSTOMERS。列表相對靜態(tài)但不完全是,在向列表中添加或從列表中刪除客戶時,表極少更改。
緩存在這一情況中也有些許用武之地。但如果您要緩存該表,如何在發(fā)生變化時確保獲得正確的數(shù)據(jù)?
Oracle 數(shù)據(jù)庫 11g 可以解決這一問題:使用 QL 結(jié)果緩存。假設(shè)查詢?nèi)缦?。運行它以獲取執(zhí)行統(tǒng)計信息和響應(yīng)時間:
SQL> set autot on explain statselectstate_code,count(*),min(times_purchased),avg(times_purchased)from customersgroup by state_code/結(jié)果是:ST COUNT(*) MIN(TIMES_PURCHASED) AVG(TIMES_PURCHASED)-- ---------- -------------------- --------------------NJ 1 15 15NY 994898 0 15.0052086CT 5099 0 14.9466562MO 1 25 25FL 1 3 35 rows selected.Elapsed: 00:00:02.57Execution Plan----------------------------------------------------------Plan hash value: 1577413243--------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |--------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 5 | 30 | 1846 (25)| 00:00:23 || 1 | HASH GROUP BY | | 5 | 30 | 1846 (25)| 00:00:23 || 2 | TABLE ACCESS FULL| CUSTOMERS | 1000K| 5859K| 1495 (7)| 00:00:18 |--------------------------------------------------------------------------------Statistics----------------------------------------------------------1 recursive calls0 db block gets5136 consistent gets5128 physical reads0 redo size760 bytes sent via SQL*Net to client420 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client0 sorts (memory)0 sorts (disk)5 rows processed幾點注意事項: 解釋計劃說明執(zhí)行了全表掃描。
共有 5,136 次連續(xù)的獲?。ㄟ壿?I/O)。
執(zhí)行時間 2.57 秒。
因為表幾乎沒變,您可以使用提示來存儲要緩存到內(nèi)存中的查詢結(jié)果:select /*+ result_cache */state_code,count(*),min(times_purchased),avg(times_purchased)from customersgroup by state_code/除提示外,查詢與第一個相同。結(jié)果(第二次執(zhí)行該查詢):ST COUNT(*) MIN(TIMES_PURCHASED) AVG(TIMES_PURCHASED)-- ---------- -------------------- --------------------NJ 1 15 15NY 994898 0 15.0052086CT 5099 0 14.9466562MO 1 25 25FL 1 3 35 rows selected.Elapsed: 00:00:00.01Execution Plan----------------------------------------------------------Plan hash value: 1577413243--------------------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |--------------------------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 5 | 30 | 1846 (25)| 00:00:23 || 1 | RESULT CACHE | gk69saf6h3ujx525twvvsnaytd | | | | || 2 | HASH GROUP BY | | 5 | 30 | 1846 (25)| 00:00:23 || 3 | TABLE ACCESS FULL| CUSTOMERS | 1000K| 5859K| 1495 (7)| 00:00:18 |--------------------------------------------------------------------------------------------------Result Cache Information (identified by operation id):------------------------------------------------------1 - column-count=4; dependencies=(ARUP.CUSTOMERS); parameters=(nls); name="select /*+ result_cache */state_code,count(*),min(times_purchased),avg(times_purchased)from customersgroup by state_c"Statistics----------------------------------------------------------0 recursive calls0 db block gets0 consistent gets0 physical reads0 redo size760 bytes sent via SQL*Net to client420 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client0 sorts (memory)0 sorts (disk)5 rows processed注意與第一次的不同之處。 響應(yīng)時間現(xiàn)在為 0.01 秒,而不是先前的將近 3 秒。
連續(xù)的獲取為 0,這一查詢沒有執(zhí)行邏輯 I/O。(事實上,首次運行帶有提示的查詢時,I/O 將保持不變,因為數(shù)據(jù)庫需要執(zhí)行 I/O 來構(gòu)建緩存。后續(xù)的調(diào)用將從緩存中供應(yīng)數(shù)據(jù),從而消除了 I/O。)
這一解釋計劃將 RESULT CACHE 視為一個操作。
解釋計劃的注意事項指明執(zhí)行的緩存類型以及緩存結(jié)果。
在時間上的節(jié)約是顯著的:從 3 秒到幾乎為 0!這是因為第二次查詢使用了緩存,結(jié)果直接來自數(shù)據(jù)庫內(nèi)存(結(jié)果緩存)而不是執(zhí)行查詢。
SQL 結(jié)果緩存是 SGA 中的另一個緩存,與緩沖區(qū)緩存或程序全局區(qū)一樣。當(dāng)您執(zhí)行帶有 result_cache提示的查詢時,Oracle 執(zhí)行該操作的過程與其他操作一樣,只是結(jié)果存儲在 SQL結(jié)果緩存中。接下來對同一查詢的調(diào)用將不訪問表,而是從緩存中獲取結(jié)果。緩存大小由幾個初始化參數(shù)確定:
參數(shù) 說明
result_cache_max_size 結(jié)果緩存上限(例如,5M 上限)。如果將它設(shè)為 0,將完全關(guān)閉結(jié)果緩存。
result_cache_max_result 指定任一結(jié)果可使用的 result_cache_max_size 百分比
result_cache_mode 如設(shè)置為 FORCE,如果緩存可以容納所有查詢,就會緩存它們。默認(rèn)值為 MANUAL 表示只緩存帶有提示的查詢。
result_cache_remote_expiration 指定訪問遠程對象的緩存結(jié)果保持有效的時間(以分鐘為單位)。默認(rèn)為 0。
現(xiàn)在,有一個邏輯問題:當(dāng)表行更改時,將發(fā)生什么情況?查詢將獲取新值還是舊值?好,讓我們來看一看。從另一個 SQL*Plus 會話更新表中的某一行:SQL> update customers set times_purchased = 42 where state_code = ‘FL‘;1 row updated.但是不要提交。在首次運行查詢的原窗口中,再運行一次。使用的是仍是緩存結(jié)果,因為更改沒有提交。運行查詢的會話仍然查看最新版本的數(shù)據(jù),緩存仍舊有效。
現(xiàn)在,從您進行更新操作的會話中,發(fā)出提交指令,然后運行查詢。
ST COUNT(*) MIN(TIMES_PURCHASED) AVG(TIMES_PURCHASED)-- ---------- -------------------- --------------------NJ 1 15 15NY 994898 0 15.0052086CT 5099 0 14.9466562MO 1 25 25FL 1 4 4注意 FL 的數(shù)據(jù)自動更新為 4。底層表的更改致使緩存無效,因而在下一次查詢它時將動態(tài)更新。無論您是否使用 SQL 結(jié)果緩存,都能保證獲得正確的結(jié)果。差異與物化視圖
熟悉物化視圖 (MV) 的人可能想這一功能與 MV的功能有什么區(qū)別。答案是:有很多區(qū)別。表面上他們很相似,都是用某種方法保存結(jié)果,從保存的數(shù)據(jù)集中提供答案,但他們的相似之處也僅限于此了。MV將數(shù)據(jù)保存在數(shù)據(jù)庫存儲中,而 SQL 結(jié)果緩存位于內(nèi)存中。它們不使用更多的磁盤空間,當(dāng)數(shù)據(jù)庫實例關(guān)閉后,它們會消失,或者result_cache 中的磁盤空間將耗盡。
MV 也是靜態(tài)的,當(dāng)?shù)讓颖碇械臄?shù)據(jù)更改時,MV 并不知道。除非您刷新 MV,否則在您將 query_rewrite_integrity設(shè)為 stale_tolerated 的情況下,用戶可能獲得的是舊數(shù)據(jù),或者用戶需要針對底層表重新運行基本查詢,而這將花費更多的時間。使用SQL 結(jié)果緩存,您不需要顯式刷新緩存;下一次運行查詢時,緩存將自動刷新。
MV提供了一個更為復(fù)雜的重寫算法。首次對結(jié)果進行緩存后,只有重新運行同一查詢或查詢片段時才會重用緩存的結(jié)果(且底層數(shù)據(jù)未更改)。受益于對 MV進行查詢重寫的查詢?nèi)钥蓮奈锘晥D上卷數(shù)據(jù),聯(lián)結(jié)回表或其他物化視圖,并應(yīng)用其他謂詞,這是數(shù)據(jù)倉庫環(huán)境中很重要的一個特點。
因此,MV 和 SQL 結(jié)果緩存是不可比或不可互換的,它們各具千秋。
子查詢
您也能在子查詢中使用 SQL 結(jié)果緩存。請看以下查詢:
select prod_subcategory, revenuefrom (select /*+ result_cache */ p.prod_category,p.prod_subcategory,sum(s.amount_sold) revenuefrom products p, sales swhere s.prod_id = p.prod_idand s.time_id between to_date(‘01-jan-1990‘,‘dd-mon-yyyy‘)and to_date(‘31-dec-2007‘,‘dd-mon-yyyy‘)group by rollup(p.prod_category, p.prod_subcategory))where prod_category = ‘software/other‘/在上面的查詢中,緩存發(fā)生在內(nèi)聯(lián)視圖的子查詢中。因此,只要內(nèi)聯(lián)查詢保持不變,外部查詢就可以更改且可使用緩存。
要檢查有多少內(nèi)存用于數(shù)據(jù)庫中的 SQL 結(jié)果緩存,您可以使用提供的程序包 dbms_result_cache,如下所示:
SQL> set serveroutput on size 999999SQL> execute dbms_result_cache.memory_reportR e s u l t C a c h e M e m o r y R e p o r t[Parameters]Block Size = 1K bytesMaximum Cache Size = 2560K bytes (2560 blocks)Maximum Result Size = 128K bytes (128 blocks)[Memory]Total Memory = 126736 bytes [0.041% of the Shared Pool]... Fixed Memory = 5132 bytes [0.002% of the Shared Pool]... Dynamic Memory = 121604 bytes [0.040% of the Shared Pool]....... Overhead = 88836 bytes....... Cache Memory = 32K bytes (32 blocks)........... Unused Memory = 21 blocks........... Used Memory = 11 blocks............... Dependencies = 4 blocks (4 count)............... Results = 7 blocks................... SQL = 5 blocks (4 count)................... Invalid = 2 blocks (2 count)PL/SQL procedure successfully completed.如果您因故想清空緩存(包括結(jié)果緩存和功能緩存,如下描述),可以使用:begindbms_result_cache.flush;end;執(zhí)行以上命令后,通過 result_cache 提示對 CUSTOMERS 運行原始查詢后,您將再次看到查詢需要 3 秒完成。
當(dāng)然,第一次運行后,結(jié)果將再次緩存,后續(xù)執(zhí)行將從結(jié)果緩存中獲取值,因此執(zhí)行速度將更快。如果您只想使一個表的緩存無效,而不是整個緩存,可以使用以下命令:
begindbms_result_cache.invalidate(‘ARUP‘,‘CUSTOMERS‘);end;有幾個數(shù)據(jù)詞典視圖列出了 SQL 結(jié)果緩存的統(tǒng)計數(shù)據(jù):
視圖 說明
V$RESULT_CACHE_STATISTICS 顯示不同的設(shè)置,特別是內(nèi)存使用
V$RESULT_CACHE_MEMORY 顯示組成 SQL 結(jié)果緩存的各內(nèi)存塊
V$RESULT_CACHE_OBJECTS 顯示組成 SQL 結(jié)果緩存的對象
V$RESULT_CACHE_DEPENDENCY 顯示組成 SQL 結(jié)果緩存的各個對象間的依賴關(guān)系
SQL 結(jié)果緩存使您能夠緩存訪問大量數(shù)據(jù)的查詢的結(jié)果。當(dāng)?shù)讓颖砀臅r,如果您沒有干預(yù)或另外編寫代碼,緩存將自動失效。PL/SQL 功能結(jié)果緩存
假設(shè)您使用一個 PL/SQL 函數(shù)(而不是 SQL查詢)來返回值。這種使用函數(shù)返回值來構(gòu)造代碼模塊的做法很常見。假設(shè)有兩個表:CUSTOMERS 存儲所有客戶的信息以及state_code。另一個表 TAX_RATE存儲每個州的稅率。要獲得適用于客戶的稅率,您需要在查詢中聯(lián)結(jié)表。因此,為簡化這一過程,您打算編寫如下函數(shù),以接受客戶 ID 作為參數(shù),并基于state_code 返回相應(yīng)的稅率:
create or replace function get_tax_rate(p_cust_id customers.cust_id%type)return sales_tax_rate.tax_rate%typeisl_ret sales_tax_rate.tax_rate%type;beginselect tax_rateinto l_retfrom sales_tax_rate t, customers cwhere c.cust_id = p_cust_idand t.state_code = c.state_code;-- simulate some time consuming-- processing by sleeping for 1 secdbms_lock.sleep (1);return l_ret;exceptionwhen NO_DATA_FOUND thenreturn NULL;when others thenraise;end;/執(zhí)行幾次函數(shù),如下所示。記住要啟用計時來記錄每次執(zhí)行使用的時間。SQL> select get_tax_rate(1) from dual;GET_TAX_RATE(1)---------------61 row selected.Elapsed: 00:00:01.23SQL> select get_tax_rate(1) from dual;GET_TAX_RATE(1)---------------61 row selected.Elapsed: 00:00:01.17每次執(zhí)行使用的時間幾乎都相同。(我特意使用了休眠語句來延遲函數(shù)內(nèi)的處理;否則返回速度太快。)如果您仔細分析代碼,將注意到每次調(diào)用函數(shù)時,幾乎都會返回相同的值??蛻舨唤?jīng)常更改所在的州,并且州的稅率也很少變化,因此對于同一個客戶,每次執(zhí)行的稅率幾乎完全相同。當(dāng)且僅當(dāng)州稅率更改或客戶搬離該州時,稅率才會變化。因此,緩存這一函數(shù)的結(jié)果會怎么樣呢?
Oracle 數(shù)據(jù)庫 11g 可讓您完成這一任務(wù)。您也可以使用 result_cache子句實現(xiàn)對函數(shù)結(jié)果的緩存。但當(dāng)州實際上更改了稅率或客戶搬離州時,又該如何呢?這一特性讓您可以指定對底層表的依賴,因此那些表中的數(shù)據(jù)更改將觸發(fā)失效操作,并隨后重建函數(shù)中的緩存。以下是添加了結(jié)果緩存代碼的同一函數(shù)(粗體):
create or replace function get_tax_rate(p_cust_id customers.cust_id%type)return sales_tax_rate.tax_rate%typeresult_cacherelies_on (sales_tax_rate, customers)isl_ret sales_tax_rate.tax_rate%type;beginselect tax_rateinto l_retfrom sales_tax_rate t, customers cwhere c.cust_id = p_cust_idand t.state_code = c.state_code;-- simulate some time consuming-- processing by sleeping for 1 secdbms_lock.sleep (1);return l_ret;exceptionwhen NO_DATA_FOUND thenreturn NULL;when others thenraise;end;/更改后,以同一方式創(chuàng)建和執(zhí)行函數(shù):SQL> select get_tax_rate(1) from dual;GET_TAX_RATE(1)---------------61 row selected.Elapsed: 00:00:01.21需要 1.21 秒,與上次使用非緩存方式一樣,但我們來看一下隨后的執(zhí)行:
 
SQL> select get_tax_rate(1) from dual;GET_TAX_RATE(1)---------------61 row selected.Elapsed: 00:00:00.01使用的時間只有 0.01 秒!到底是怎么回事?函數(shù)執(zhí)行第一次時,耗時 1.21 秒。但這一次的重要區(qū)別是它在執(zhí)行時緩存了結(jié)果。后續(xù)的調(diào)用不執(zhí)行該函數(shù),只從緩存中獲取結(jié)果。因此,它沒有休眠函數(shù)代碼中指定的 1 秒鐘。
緩存只針對 customer_id 1。如果針對另一個客戶執(zhí)行函數(shù),又會如何?
SQL> select get_tax_rate(&n) from dual;Enter value for n: 5old 1: select get_tax_rate(&n) from dualnew 1: select get_tax_rate(5) from dualGET_TAX_RATE(5)---------------61 row selected.Elapsed: 00:00:01.18SQL> /Enter value for n: 5old 1: select get_tax_rate(&n) from dualnew 1: select get_tax_rate(5) from dualGET_TAX_RATE(5)---------------61 row selected.Elapsed: 00:00:00.00SQL> /Enter value for n: 6old 1: select get_tax_rate(&n) from dualnew 1: select get_tax_rate(6) from dualGET_TAX_RATE(6)---------------61 row selected.Elapsed: 00:00:01.17您可以看到,首次執(zhí)行每個參數(shù)時,它會緩存結(jié)果。后續(xù)的調(diào)用從緩存中檢索值。隨著您針對各個客戶執(zhí)行該函數(shù),緩存會逐漸增大。
注意函數(shù)代碼中的“relies on”子句。它將告知函數(shù)緩存依賴哪兩個表:customers 和 tax_rate。如果那些表中的數(shù)據(jù)更改,那么緩存就需要刷新。刷新會自動發(fā)生,不需要您干預(yù)。如果數(shù)據(jù)未更改,緩存將繼續(xù)盡可能快地提供緩存的值。
如果因故要繞過緩存,您可以調(diào)用提供的程序包 DBMS_RESULT_CACHE 中的過程:
SQL> exec dbms_result_cache.bypass(true);PL/SQL procedure successfully completed.Elapsed: 00:00:00.01SQL> select get_tax_rate(&n) from dual;Enter value for n: 6old 1: select get_tax_rate(&n) from dualnew 1: select get_tax_rate(6) from dualGET_TAX_RATE(6)---------------61 row selected.Elapsed: 00:00:01.18從執(zhí)行時間上可以看出,沒有使用緩存。緩存與程序包變量
對 SQL 結(jié)果緩存和 PL/SQL 函數(shù)緩存,您也可以使用程序包變量(可以是標(biāo)量數(shù)據(jù)類型或 PL/SQL 集合)實現(xiàn)在內(nèi)存中緩存值。應(yīng)用程序可以訪問變量,而不是表行或函數(shù)。因為基于內(nèi)存,它的行為像緩存,那么 SQL 結(jié)果緩存添加了什么值?
差別眾多。對一個客戶(假設(shè) cust_id = 5)執(zhí)行該函數(shù)后,從另一個 會話對同一客戶執(zhí)行該函數(shù):
SQL> select get_tax_rate(&n) from dual2 /Enter value for n: 5old 1: select get_tax_rate(&n) from dualnew 1: select get_tax_rate(5) from dualGET_TAX_RATE(5)---------------61 row selected.Elapsed: 00:00:00.00注意執(zhí)行時間,它表明結(jié)果源自緩存,而不是通過函數(shù)的執(zhí)行。因此,盡管會話中沒有緩存該函數(shù),任一調(diào)用它的會話仍然可以從緩存中使用它。
 
緩存針對數(shù)據(jù)庫實例,而不是會話。這一讓所有其他會話能使用一個會話中的緩存的能力極其不同于使用程序包變量在內(nèi)存中保存值的方法,在這一方法中,變量只能在一個會話中可見。
而且,程序包變量無法感知底層表的更改。當(dāng)數(shù)據(jù)更改時,您需要手動刷新數(shù)據(jù),否則應(yīng)用程序?qū)@取陳舊數(shù)據(jù)。在底層表數(shù)據(jù)更改時,SQL 結(jié)果緩存和 PL/SQL 函數(shù)緩存會自動刷新緩存,不需用戶介入。
客戶端查詢結(jié)果緩存
假設(shè)有這樣一個情形:客戶端需要通過慢速網(wǎng)絡(luò)鏈接調(diào)用同一數(shù)據(jù)。盡管數(shù)據(jù)庫可以立即將結(jié)果從緩存發(fā)送到客戶端,但結(jié)果必須通過線路傳送到客戶端,這就增加了整體執(zhí)行時間?,F(xiàn)在有一些專門的中間件框架(如 Oracle Coherence),用于在 Java、PHP 和 Ruby中緩存數(shù)據(jù),如果有一個在客戶端級別緩存數(shù)據(jù)的通用方法,又將如何呢?
為此,Oracle 數(shù)據(jù)庫 11g 提供了“客戶端查詢結(jié)果緩存”。所有使用 OCI8 驅(qū)動程序的數(shù)據(jù)庫客戶端堆棧(C、C++、JDBC-OCI 等)都可以使用這一新特性,使客戶端能夠在本地緩存 SQL 查詢的結(jié)果,而不是在服務(wù)器上??傃灾?,客戶端查詢結(jié)果緩存可以提供以下好處:
使應(yīng)用程序開發(fā)人員不用構(gòu)建由所有會話共享的一致的每一流程的 SQL 結(jié)果緩存
通過利用更便宜的客戶端內(nèi)存并在本地緩存每個應(yīng)用程序的工作集,將服務(wù)器端查詢緩存擴展到客戶端內(nèi)存,
從而消除到服務(wù)器的往返過程,確保更好的性能
通過節(jié)約服務(wù)器資源,改善服務(wù)器可伸縮性
提供透明的緩存管理:內(nèi)存管理、結(jié)果集的并發(fā)訪問等
透明地維護緩存與服務(wù)器端更改的一致性
在 RAC 環(huán)境中提供一致性
要使用這一特性,您所要做的就是設(shè)置一個初始化參數(shù):CLIENT_RESULT_CACHE_SIZE = 1G該參數(shù)定義客戶端緩存為 1GB,這是所有客戶端的總緩存大小。(這是一個靜態(tài)參數(shù),因此您必須重啟數(shù)據(jù)庫來設(shè)置它。)您可以在每個客戶端中設(shè)置緩存,在客戶端位置的 SQLNET.ORA 文件中指定其他參數(shù):
參數(shù) 說明
OCI_RESULT_CACHE_MAX_SIZE 指定該特定客戶端的緩存大小
OCI_RESULT_CACHE_MAX_RSET_SIZE 指定結(jié)果集大小的上限
OCI_RESULT_CACHE_MAX_RSET_ROWS 同上,但指定結(jié)果集行數(shù)的上限
讓我們看一看它的使用方式。這是簡單的 Java 代碼,它使用 OCI8 驅(qū)動程序連接到數(shù)據(jù)庫,然后執(zhí)行 SQL 語句:select /*+ result_cache */ * from customers。提示致使語句緩存該結(jié)果(其他參數(shù)已經(jīng)設(shè)置好)。import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;public class CacheTest {private String jdbcURL = "jdbc:oracle:oci8:@PRONE3";private Connection conn = null;public CacheTest( ) throws ClassNotFoundException {Class.forName("oracle.jdbc.driver.OracleDriver");}public static void main(String[] args) throws ClassNotFoundException, SQLException {CacheTest check = new CacheTest();check.dbconnect();check.doSomething();}public void dbconnect() throws SQLException {System.out.println("Connecting with URL="+jdbcURL+" as arup/arup");try {conn = DriverManager.getConnection( jdbcURL, "arup" , "arup");System.out.println("Connected to Database");} catch (SQLException sqlEx) {System.out.println(" Error connecting to database : " + sqlEx.toString());}}public void doSomething() throws SQLException {Statement stmt = null;ResultSet rset = null;try {stmt = conn.createStatement();System.out.println("Created Statement object");rset = stmt.executeQuery("select /*+ result_cache */ * from customers");System.out.println("Retrieved ResultSet object");if(rset.next())System.out.println("Result:"+rset.getString(1));} catch (SQLException sqlEx) {} finally {try {System.out.println("Closing Statment & ResultSet Objects");if (rset != null) rset.close();if (stmt != null) stmt.close();if (conn != null) {System.out.println("Disconnecting...");conn.close();System.out.println("Disconnected from Database");}} catch (Exception e) { }}}}將文件保存為 CacheTest.java,然后編譯代碼:
 
$ORACLE_HOME/jdk/bin/javac CacheTest.java現(xiàn)在,執(zhí)行編譯后的類:$ORACLE_HOME/jdk/bin/java -classpath .:$ORACLE_HOME/jdbc/lib/ojdbc5.jar CacheTestConnecting with URL=jdbc:oracle:oci8:@PRONE3 as arup/arupConnected to DatabaseCreated Statement objectRetrieved ResultSet objectResult :MClosing Statment & ResultSet ObjectsDisconnecting...Disconnected from Database多執(zhí)行幾次。幾次執(zhí)行之后,您可以發(fā)現(xiàn)客戶端已通過動態(tài)視圖對值進行了緩存,如下所示:select * from client_result_cache_stats$/select * from v$client_result_cache_stats/客戶端查詢結(jié)果緩存在查找很少改變的表時十分有用。(即使它們更改,也會刷新緩存。)這與 SQL結(jié)果緩存不同,其緩存位于服務(wù)器上。由于客戶端緩存了結(jié)果,因此不需要在客戶端與服務(wù)器間往返以獲取數(shù)據(jù) — 這不但節(jié)省了網(wǎng)絡(luò)帶寬,還節(jié)省了服務(wù)器CPU 周期。有關(guān)更多信息,請參閱Oracle 調(diào)用接口編程人員指南。數(shù)據(jù)庫駐留連接池
在傳統(tǒng)的客戶端/服務(wù)器體系結(jié)構(gòu)中,用戶會話和數(shù)據(jù)庫連接之間是一對一的通信。但在基于 Web 的系統(tǒng)中,情況可能有所不同。
基于 Web 的系統(tǒng)在本質(zhì)上是“無狀態(tài)”的 — 當(dāng)您訪問頁面時,將建立與數(shù)據(jù)庫的連接,頁面下載完成后,將切斷與數(shù)據(jù)庫的連接。稍后,當(dāng)用戶再次單擊頁面時,將建立一個新的連接,目的達到后又將切斷連接。這一過程使得沒有必要維護大量的同步連接。
建立連接的開銷很大,因此連接池是這些應(yīng)用程序的一個重要要求。在這一模式中,當(dāng)頁面需要數(shù)據(jù)庫訪問時,會從池中分配一個已經(jīng)建立的連接。完成工作后,Web 會話會將連接返回池中。
但傳統(tǒng)的客戶端或中間層連接池的問題是: 每個池只限于單個中間層節(jié)點。
池的大量增長將導(dǎo)致預(yù)先分配的數(shù)據(jù)庫服務(wù)器過多和數(shù)據(jù)庫服務(wù)器內(nèi)存使用過多。
池中的工作負載分配不均。
為避免這些問題,Oracle 數(shù)據(jù)庫 11g 提供了一個服務(wù)器端池,稱為數(shù)據(jù)庫駐留連接池 (DRCP)。DRCP 可用于使用 OCI 驅(qū)動程序的所有數(shù)據(jù)庫客戶端,包括 C、C++ 和 PHP。
 
Oracle 數(shù)據(jù)庫 11g 預(yù)先安裝有默認(rèn)的連接池,但是處于關(guān)閉狀態(tài)。要啟用它,使用:execute dbms_connection_pool.start_pool;現(xiàn)在,要連接到池中的連接而不是常規(guī)會話,您要做的就是在 TNS 條目中添加一行 (SERVER=POOLED),如下所示:PRONE3_POOL =(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = prolin3.proligence.com)(PORT = 1521))(CONNECT_DATA = (SERVER = POOLED)(SID = PRONE3)))現(xiàn)在,更改代碼中的 connect 字符串,在這一代碼中它連接到數(shù)據(jù)庫。使用上面“客戶端結(jié)果緩存”部分中的示例代碼:private String jdbcURL = "jdbc:oracle:oci8:@PRONE3_POOL";就這樣了?,F(xiàn)在,您的應(yīng)用程序?qū)⑦B接到池而不是服務(wù)器。如果您使用瘦客戶端且使用標(biāo)準(zhǔn)的 JDBC 連接字符串,則可以使用 POOLED 子句:prolin3. proligence.com:1521/PRONE3:POOLED在上面的描述中,您啟用了 Oracle 附帶的默認(rèn)池,選項為默認(rèn)的。您可以使用提供的 DBMS_CONNECTION_POOL 程序包中的 CONFIGURE_POOL 過程:
參數(shù)
說明
POOL_NAME
池的名稱。使用 ‘’(兩個單引號用于默認(rèn)池)
MINSIZE
池中保存會話數(shù)量的下限
MAXSIZE
池中會話數(shù)量的上限
INCRSIZE
當(dāng)池中的服務(wù)器不可用時,池將創(chuàng)建這一數(shù)量的新服務(wù)器
SESSION_CACHED_CURSORS
啟用會話緩存游標(biāo)
INACTIVITY_TIMEOUT
如果會話閑置時間達到這一時長,將斷開。
MAX_THINK_TIME
當(dāng)客戶端從池中獲取一個服務(wù)器后,它必須在這一時間段內(nèi)發(fā)出 SQL 語句,否則客戶端將丟失服務(wù)器
MAX_USE_SESSION
從池中取還一個連接的最多次數(shù)
MAX_LIFETIME_SESSION
會話的持續(xù)時間
DRCP 功能非常重要,因為單個池可在一個普通平臺上維持?jǐn)?shù)萬同步用戶。此外,單個池可以在多個客戶端和中間層節(jié)點間共享,并且在 RAC 和 Data Guard 環(huán)境中,DRCP 和 FAN 事件共同提供了快速的連接故障轉(zhuǎn)移。
返回到“Oracle 數(shù)據(jù)庫 11g:面向 DBA 和開發(fā)人員的重要特性”主頁
Arup Nanda (arup@proligence.com)擔(dān)任專職 Oracle DBA 已愈 12 年,他擁有 Oracle 數(shù)據(jù)庫技術(shù)各個領(lǐng)域的經(jīng)驗,2003 年被 Oracle 雜志授予“年度DBA”稱號。Arup 經(jīng)常在 Oracle 相關(guān)的活動中發(fā)表演講并為 Oracle 相關(guān)刊物撰寫文章,他還是一位Oracle ACE 總監(jiān)。他與其他人合作編寫了四本書,其中包括《RMAN Recipes for Oracle Database 11g:A Problem Solution Approach》。
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
數(shù)據(jù)庫與服務(wù)器有什么區(qū)別
oracle數(shù)據(jù)庫執(zhí)行sql文件
從Select語句看Oracle查詢原理
oracle數(shù)據(jù)庫中查詢連接數(shù)的實用sql語句
1.oracle登陸
Oracle 概念(Oracle 10.2) 第八章 內(nèi)存結(jié)構(gòu)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服