oracle的一些調優建議(1)

2021-08-30 10:41:17 字數 3044 閱讀 7945

1. 選用適合的oracle優化器

oracle的優化器共有3種:

a. rule (基於規則) b. cost (基於成本) c. choose (選擇性)

設定預設的優化器,可以通過對init.ora檔案中optimizer_mode引數的各種宣告,如rule,cost,choose,all_rows,first_rows . 你當然也在sql句級或是會話(session)級對其進行覆蓋.

為了使用基於成本的優化器(cbo, cost-based optimizer) , 你必須經常執行analyze 命令,以增加資料庫中的物件統計資訊(object statistics)的準確性.

如果資料庫的優化器模式設定為選擇性(choose),那麼實際的優化器模式將和是否執行過analyze命令有關. 如果table已經被analyze過, 優化器模式將自動成為cbo , 反之,資料庫將採用rule形式的優化器.

在預設情況下,oracle採用choose優化器, 為了避免那些不必要的全表掃瞄(full table scan) , 你必須盡量避免使用choose優化器,而直接採用基於規則或者基於成本的優化器.

2. 訪問table的方式

oracle 採用兩種訪問表中記錄的方式:

a.       全表掃瞄

全表掃瞄就是順序地訪問表中每條記錄. oracle採用一次讀入多個資料塊(database block)的方式優化全表掃瞄.

b.       通過rowid訪問表

你可以採用基於rowid的訪問方式情況,提高訪問表的效率, , rowid包含了表中記錄的物理位置資訊..oracle採用索引(index)實現了資料和存放資料的物理位置(rowid)之間的聯絡. 通常索引提供了快速訪問rowid的方法,因此那些基於索引列的查詢就可以得到效能上的提高.

3. 共享sql語句

為了不重複解析相同的sql語句,在第一次解析之後, oracle將sql語句存放在記憶體中.這塊位於系統全域性區域sga(system global area)的共享池(shared buffer pool)中的記憶體可以被所有的資料庫使用者共享. 因此,當你執行乙個sql語句(有時被稱為乙個游標)時,如果它和之前的執行過的語句完全相同, oracle就能很快獲得已經被解析的語句以及最好的執行路徑. oracle的這個功能大大地提高了sql的執行效能並節省了記憶體的使用.

資料庫管理員必須在init.ora中為這個區域設定合適的引數,當這個記憶體區域越大,就可以保留更多的語句,當然被共享的可能性也就越大了.

當你向oracle 提交乙個sql語句,oracle會首先在這塊記憶體中查詢相同的語句.

這裡需要註明的是,oracle對兩者採取的是一種嚴格匹配,要達成共享,sql語句必須

完全相同(包括空格,換行等).

例如:

select * from emp;

和下列每乙個都不同

select * from emp;

select * from emp;

select * from emp;

使用繫結變數 (bind variable)

shared_pool 快取已經被解析過的sql,而使其能被重用,不再解析。這樣做的原因是因為,對於乙個新的sql(shared_pool裡面不存在已經解析的可用的相同的sql),資料庫將執行硬解析,這是乙個很消耗資源的過程。而若已經存在,則進行的僅僅是軟分析(在共享池中尋找相同sql),這樣消耗的資源大大減少。

沒有使用bind var 的sql,我們稱為literal sql。也就是比如這樣的兩句sql,oracle認為是不同的sql,需要進行2次硬解析:

select * from emp where name = 『tom』;

select * from emp where name = 『jerry』;

假如把』tom』 和 『jerry』 換做變數v,那就是使用了bind var,可以認為是同樣的sql從而能很好地共享。共享sql本來就是shared_pool_size這部分記憶體存在的本意,oracle的目的也在於此,而我們不使用bind var就是違背了oracle的初衷,這樣將給我們的系統帶來嚴重的問題。

select * from emp where name = :v;

5. where子句中的連線順序

oracle採用自下而上的順序解析where子句,根據這個原理,表之間的連線必須寫在其他where條件之前, 那些可以過濾掉最大數量記錄的條件必須寫在where子句的末尾.

例如:(低效,執行時間156.3秒)

select … 

from emp e

where sal > 50000

and job = 『manager』

and 25 < (select count(*) from emp

where mgr=e.empno);

(高效,執行時間10.6秒)

select … 

from emp e

where 25 < (select count(*) from emp

where mgr=e.empno)

and sal > 50000

and job = 『manager』;

6. select子句中避免使用 『 * 『

當你想在select子句中列出所有的column時,使用動態sql列引用 『*』 是乙個方便的方法.不幸的是,這是乙個非常低效的方法. 實際上,oracle在解析的過程中, 會將』*』 依次轉換成所有的列名, 這個工作是通過查詢資料字典完成的, 這意味著將耗費更多的時間.

7. 刪除重覆記錄

最高效的刪除重覆記錄方法 ( 因為使用了rowid)

delete from emp e

where e.rowid > (select min(x.rowid)

from emp x

where x.emp_no = e.emp_no);

關於有效的效能調優的一些建議

只有採用有效的效能調優手段,才能使得效能調優達到事倍功半的效果。近日,個人部落格liguanglei中發布了一篇關於有效效能調優建議的文章,該篇文章是作者閱讀 效能調優 綜合指南 的讀書筆記。作者從影響系統效能的演算法 演算法執行環境與所需資源以及演算法和環境資源的互動等因素講述了效能調優的一些建議...

關於有效的效能調優的一些建議

只有採用有效的效能調優手段,才能使得效能調優達到事倍功半的效果。近日,個人部落格liguanglei中發布了一篇關於有效效能調優建議的文章,該篇文章是作者閱讀 效能調優 綜合指南 的讀書筆記。作者從影響系統效能的演算法 演算法執行環境與所需資源以及演算法和環境資源的互動等因素講述了效能調優的一些建議...

關於有效的效能調優的一些建議

只有採用有效的效能調優手段,才能使得效能調優達到事倍功半的效果。近日,個人部落格liguanglei中發布了一篇關於有效效能調優建議的文章,該篇文章是作者閱讀 效能調優 綜合指南 的讀書筆記。作者從影響系統效能的演算法 演算法執行環境與所需資源以及演算法和環境資源的互動等因素講述了效能調優的一些建議...