佳木斯湛栽影视文化发展公司

主頁 > 知識庫 > 解析Oracle 8i/9i的計劃穩(wěn)定性

解析Oracle 8i/9i的計劃穩(wěn)定性

熱門標(biāo)簽:鐵路電話系統(tǒng) 百度競價排名 網(wǎng)站排名優(yōu)化 服務(wù)外包 Linux服務(wù)器 呼叫中心市場需求 地方門戶網(wǎng)站 AI電銷
正在看的ORACLE教程是:解析Oracle 8i/9i的計劃穩(wěn)定性。

由Oralce8.1開始,Oracle增加了一個新的特性就是Stored Outlines,或者稱為Plan Stability(計劃穩(wěn)定性)。這個特性帶來三個好處。首先,你可以優(yōu)化開銷很大的語句的處理。第二,如果有一些語句Oracle需要花費長時間來優(yōu)化(而不是執(zhí)行),你可以節(jié)省時間并且減少優(yōu)化階段的競爭。最后,它可以讓你選擇使用新的cursor_sharing參數(shù)而無需要擔(dān)心因此而不采用優(yōu)化的執(zhí)行路徑。

  要知道如何使用存儲概要才是最優(yōu)的,我們首先運行一些極度沒有效率的SQL的存儲過程開始,要注意的是,我們不能修改源代碼(理論上)。
 
  我們將看一下如何跟蹤SQL語句,并且查看它當(dāng)前在數(shù)據(jù)庫中的執(zhí)行計劃,找出一些提示來改進SQL語句的性能,然后再重新執(zhí)行該SQL語句時,讓Oracle使用我們的提示。

  在這個示例中,我們將創(chuàng)建一個用戶,在該用戶的模式中建一個表格,并且創(chuàng)建一個存儲過程訪問該表格,我們將在這個存儲過程上使用wrap工具,這樣我們就不能通過反向方式得到源代碼。然后我們將通過該存儲過程來調(diào)試SQL的執(zhí)行。

  例子中我們將假定存儲慨要已經(jīng)在數(shù)據(jù)庫創(chuàng)建的時候被自動安裝。

  準(zhǔn)備工作

  創(chuàng)建一個用戶,他的權(quán)限有:create session, create table, create procedure, create any outline, and alter session。以該用戶連接并且運行以下的腳本來創(chuàng)建一個表格:


  接著需要編碼來創(chuàng)建一個存儲過程訪問該表格。創(chuàng)建一個稱為c_proc.sql的腳本,如下:


  當(dāng)然,也可以直接執(zhí)行這個腳本來建立該過程--不過,為了更有效果,轉(zhuǎn)到操作系統(tǒng)的命令行并且執(zhí)行以下命令:

  wrap iname=c_proc.sql

  響應(yīng)是:

  Processing c_proc.sql to c_proc.plb

  這里不是通過執(zhí)行c_proc.sql腳本來產(chǎn)生該過程,而是執(zhí)行看不到源碼的c_proc.plb腳本,你將會發(fā)現(xiàn)在user_source的視圖中找不到我們的SQL語句。

[NextPage]

這個應(yīng)用的作用是什么?

  現(xiàn)在我們已經(jīng)產(chǎn)生了一個模擬的應(yīng)用,我們就可以運行它,打開sql_trace,看看有什么事情發(fā)生。我們將會發(fā)現(xiàn)這個SQL執(zhí)行一個全表搜索來得到請求的數(shù)據(jù)。

  在這個測試中,全表檢索或許是最有效的方式--不過讓我們假定已經(jīng)證明使用一個單列的索引和and-equal選項才是最佳的執(zhí)行路徑時,我們可以怎樣修改呢(無需在代碼中加入提示)?

  通過存儲概要,答案是簡單的。要達到我下面所做的事情實際上有好幾種方法,因此不要認(rèn)為這是唯一的做法。Oracle一直改進它的特性以方便使用,這里所講的技術(shù)或許在未來的一個版本中就會消失。

  你想該應(yīng)用做什么?

  要令Oracle如我們所想的那樣運作,有三個階段:

  . 啟動一個新的session(連接),然后重新運行該過程,首先告訴Oracle我們要跟蹤將要運行的SQL語句和該SQL使用的路徑。這里說的"路徑"就是我們存儲概要的第一個例子。

  . 為有問題的SQL語句創(chuàng)建更好的存儲概要,然后用好的代替有問題的。

  . 啟動一個新的session,并且告訴Oracle在看到匹配的SQL時,開始使用新的存儲概要,而不是使用通常的優(yōu)化方法來執(zhí)行;然后重新運行該過程。

  我們必須停止和啟動新的session來確保pl/sql緩沖中的游標(biāo)(cursors)并不是保持打開的。存儲概要只在一個游標(biāo)被分析的時候產(chǎn)生和(或)應(yīng)用,因此我們必須要確認(rèn)以前存在的類似游標(biāo)是關(guān)閉的。

  啟動一個session并且執(zhí)行以下的命令:

alter session set create_stored_outlines = demo;

  然后運行一小段匿名的代碼塊來執(zhí)行該過程,例如:


  然后停止收集執(zhí)行的路徑(否則以下你執(zhí)行的一些SQL也會放到存儲概要的表格中,令接下來的處理有點困難)。

  alter session set create_stored_outlines = false;

  要看到這樣做的結(jié)果,我們可以查詢以下視圖來看清Oracle為我們創(chuàng)建和存儲的概要細節(jié)。。


  我們可以看到在demo的分類中只有一個存儲概要,查看概要中的sql_text我們可以看到與我們原來PL/SQL代碼類似的、但又有點不同的語句。這是很重要的一點,因為Oracle僅在存儲的sql_text和將要執(zhí)行的SQL非常相似的時候才會使用存儲概要。實際上,在Oracle8i中,兩個SQL語句要完全一樣才可以,這也是存儲概要的一個大問題。

  你可以由列表中看到存儲概要中是一套hints用來描述Oracle如何執(zhí)行(或者將要執(zhí)行)該SQL。這個計劃使用一個全表搜索--即使是一個全表搜索這樣的操作,Oracle使用大量的hints來確保執(zhí)行的計劃。

  要注意到存儲概要通常都是屬于一個分類的;在這里是demo分類,我們是通過alter session命令來指定的。如果在上面的命令中,我們使用true來代替demo,我們將在一個名字為default的分類中找到該存儲概要。

  存儲概要都有一個名字,該名字在整個數(shù)據(jù)庫中都必須是唯一的。沒有兩個概要的名字是相同的,即使是它們是由不同的用戶產(chǎn)生。實際上,概要并不是由誰擁有的,它們僅有創(chuàng)建者。如果你創(chuàng)建的一個存儲概要和我以后執(zhí)行的一個SQL語句匹配,Oracle將會應(yīng)用你的hints列表到我的語句--即使這些hints在我的模式中是無意義的。(這樣我們就有完全不同的選項來欺騙存儲概要,不過這是另一篇文章的事情了)。你還可能注意到,當(dāng)Oracle自動產(chǎn)生存儲概要時,它的名字中包含有一個接近毫秒的時間戳。

  繼續(xù)處理我們那個有問題的SQL,我們判定如果使用一個/*+ and_equal(so_demo, sd_i1, sd_i2) */ 的hint,那么Oracle將會使用我們想要的執(zhí)行路徑,所以我們現(xiàn)在通過以下的方法顯式創(chuàng)建一個存儲概要:


  這樣就顯式地在我們的demo分類中創(chuàng)建了一個名字為so_fix的存儲概要。我們可以通過name='SO_FIX'這個條件來重新查詢user_outlines和user_outline_hints,查看一下存儲概要是怎樣的。


  要注意到的是FULL(SO_DEMO)那一行已經(jīng)被AND_EQUAL(SO_DEMO SD_I1 SD_I2)替換了,這是我們想要看到的。

  現(xiàn)在我們必須將兩個存儲概要"替換"過來。我們想Oracle在看到以前的語句時使用新的hint列表;要做到這一點,我們必須做一些欺騙。user_outlines和user_outline_hints視圖是由兩個表格產(chǎn)生的(分別是ol$和ol$hints),它們由outln模式擁有,我們必須直接修改這些表格;這意味著要使用outln連接數(shù)據(jù)庫,并且使用一個有權(quán)限的帳號來更新表格。

  幸運的是,outln表格并沒有任何引用的完整性限制。便利的是,ol$ (outlines)和ol$hints (hints) 表格間的關(guān)系是由概要的名字定義的(存儲在ol_name列中)。因此,仔細檢查名字,我們就可以通過交換ol$hints表上的名字交換存儲概要的提示:



  對于這樣做,你可能感到有點不習(xí)慣,特別是根據(jù)指南上的建議--不過這個更新在Metalink(譯者注:這是Oracle的一個技術(shù)支持站點)上是允許的。不過,你還需要做第二次更新來確保和每個存儲概要相聯(lián)系的hints數(shù)目保持一致。如果你忽略了這一步,你將會發(fā)現(xiàn)你的一些存儲概要被損壞,或者在一個導(dǎo)出/導(dǎo)入中的處理中被破壞。


  一旦完成上面的語句,你就可以發(fā)起一個新的連接,告訴它使用存儲概要,重新運行該過程然后退出;同樣地,你可以使用sql_trace來確認(rèn)Oracle確實是這樣做的。要告訴Oracle使用修改后的存儲概要,你可以使用以下的命令:

alter session set use_stored_outline =&nb

[1] [2] 下一頁

正在看的ORACLE教程是:解析Oracle 8i/9i的計劃穩(wěn)定性。sp;demo;

  檢查trace文件,你將會發(fā)現(xiàn)該SQL現(xiàn)在使用and_equal的路徑(如果你使用tkprof來處理和解釋trace文件,你將會發(fā)現(xiàn)輸出顯示了兩個矛盾的路徑。第一個將展示使用的and_equal路徑,第二個將可能是一個全表搜索,這是因為在tkprof在跟蹤的SQL上執(zhí)行explain plan時,該存儲概要可能沒有被調(diào)用)。

[NextPage]

 由開發(fā)到生成環(huán)境

  現(xiàn)在我們已經(jīng)產(chǎn)生了一個單一的概要,我們需要將它傳送到生產(chǎn)環(huán)境中。存儲概要有很多特性可以幫助我們做到這一點。例如,我們可以將存儲概要改名,由開發(fā)環(huán)境中導(dǎo)出,然后將它導(dǎo)入到生產(chǎn)系統(tǒng)中,首先在生產(chǎn)環(huán)境的一個測試分類中檢驗它,然后在將它轉(zhuǎn)移到生產(chǎn)分類中。有用的命令是:

alter outline SYS_OUTLINE_020503165427311 rename to AND_EQUAL_SAMPLE;
alter outline AND_EQUAL_SAMPLE change category to PROD_CAT;

  要將概要由一個開發(fā)系統(tǒng)導(dǎo)出到一個生產(chǎn)系統(tǒng)中,我們可以利用在一個導(dǎo)出的參數(shù)文件中加入一個where語句,因此我們的導(dǎo)出參數(shù)文件可能是:


  Oracle 9的加強

  在使用存儲概要時,還有許多其它的細節(jié)需要考慮,在Oracle8中,對于它們能夠做什么以及如何工作是有一些不便的限制的,不過其中許多的問題已經(jīng)在Oracle 9中消除了。

  存儲概要在Oracle8中使用的最大不足是它只可以在存儲的文本和將要執(zhí)行的文本要完全一樣才可以使用。在Oracle 9中,有一個"標(biāo)準(zhǔn)化"的處理可以消除這個匹配的限制;在對比前,文本將會被轉(zhuǎn)換為大寫并且被除去空格。這樣就提升了不同的SQL可以使用同一個存儲概要的機會。

  調(diào)用多個存儲塊的復(fù)雜執(zhí)行計劃中還有一些問題。Oracle公司通過在Oracle 9中推出了一個在outln模式中的ol$nodes表來解決。這樣就可以幫助Oracle減少ol$hints中的hints列表,并且可以在即將執(zhí)行SQL的子區(qū)中正確地交叉應(yīng)用它們。不過,由存儲概要之間交換hints的策略有一個副作用,因為ol$hints表還需要不同細節(jié)的文本長度和偏移。升級到Oracle9時,將需要選用一些方法來管理存儲概要,例如帶有特別數(shù)據(jù)集合或者丟失索引的第二個模式,或者是帶有內(nèi)置的hints的存儲視圖來替換文本中命名的表格。

  Oracle9的另一個特色是在管理存儲概要時有更多的支持,包括初次推出了一個包來讓你直接編輯存儲概要。更重要的是,還有一個選項可讓你更安全地管理生產(chǎn)系統(tǒng)上的計劃。雖然沒人喜歡在生產(chǎn)環(huán)境上做實驗,不過在有些時候,只有生產(chǎn)系統(tǒng)才有正確的數(shù)據(jù)分布和卷,以讓你決定某個SQL的最優(yōu)執(zhí)行路徑。在Oracle9中,你可以創(chuàng)建一個outln表的私人拷貝,并且將"public"的概要釋放進去以作"私人的"實驗,這樣你就不用冒你的私人存儲概要被終端用戶的代碼看到的危險。我個人認(rèn)為這是一個最后的手段,不過我可以想象到有時它是必須的。更安全的是,如果你有一個full-scale UAT或者開發(fā)系統(tǒng),可以使用這個特性自由地測試。

  告誡

  這篇文章給你足夠的信息作存儲概要的實驗;不過在應(yīng)用該技術(shù)到一個生產(chǎn)系統(tǒng)上時,還有一些地方是你必須意識到的。

  首先--在Oracle8i中,outln(這是擁有存儲概要的那些表格所在的模式)有一個默認(rèn)的密碼,該帳號有一個非常危險的權(quán)限。你必須修改這個帳號的密碼。在Oracle9i中,你將會發(fā)現(xiàn)這個帳號已經(jīng)被鎖定。

  第二--保持存儲概要的表格在system表空間中創(chuàng)建。在一個生產(chǎn)系統(tǒng)中,當(dāng)你開始創(chuàng)建存儲概要時,你將會發(fā)現(xiàn)會使用system表空間中的很多空間。因此最好將這些表格移走,最好是放到它們自己的表空間中。不幸的是,其中的一個表格含有l(wèi)ong列,因此你將可能需要使用exp/imp將這些表格移動到一個新的表空間中。

  第三--雖然存儲概要對于解決嚴(yán)重的性能問題是很有用的,不過它也有一個開銷。如果激活了存儲概要,那么Oracle在分析每個新的語句時都會檢查是否存在一個相關(guān)的存儲概要。如果大量的語句都沒有存儲概要,那么你就需要平衡一下這個開銷與你在很少擁有存儲概要語句上得到的性能提升,看是否值得這樣處理。不過,這個問題只會在一個有著更嚴(yán)重性能問題的系統(tǒng)上出現(xiàn)。

  結(jié)論

  存儲概要有著巨大的好處。當(dāng)你不能修改源代碼或者索引策略時,存儲概要是令第三方的應(yīng)用運行得更有效率的唯一方法。

  更進一步,如果你還需要面對將一個系統(tǒng)由基于規(guī)則切換到開銷優(yōu)先的問題,那么存儲概要將是你最有效率和無風(fēng)險的選擇。

  如果你需要發(fā)揮存儲概要的最大好處,那么Oracle9有一些加強可讓它覆蓋更多類的SQL,減少開銷,并可讓你更靈活地測試、管理和安裝存儲概要。

上一頁     

上一頁  [1] [2] 

標(biāo)簽:銅川 崇左 仙桃 黃山 蘭州 衡水 湖南 湘潭

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《解析Oracle 8i/9i的計劃穩(wěn)定性》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266
    辉县市| 兰坪| 光泽县| 罗甸县| 千阳县| 静乐县| 西青区| 石渠县| 肥东县| 抚远县| 高阳县| 全州县| 伊金霍洛旗| 昌江| 德江县| 封开县| 卢龙县| 大竹县| 梨树县| 个旧市| 木兰县| 富平县| 曲阳县| 泰兴市| 宜章县| 鱼台县| 丘北县| 中西区| 东莞市| 团风县| 昆山市| 枞阳县| 娱乐| 绵阳市| 莱芜市| 武川县| 镶黄旗| 光泽县| 乐安县| 平泉县| 盐山县|