Oracle SQL效能優化深入淺出1

2021-12-30 05:29:35 字數 3860 閱讀 8850

oracle將執行過的sql語句存放在記憶體的共享池(shared buffer pool)中,可以被所有的資料庫使用者共享。當你執行乙個sql語句(有時被稱為乙個游標)時,如果它和之前的執行過的語句完全相同, 

oracle就能很快獲得已經被解析的語句以及最好的執行路徑. 這個功能大大地提高了sql的執行效能並節省了記憶體的使用。 

www.2cto.com  

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

可惜的是,oracle只對簡單的表提供高速緩衝(cache buffering),這個功能並不適用於多表連線查詢。資料庫管理員必須在啟動引數檔案中為這個區域設定合適的引數,當這個記憶體區域越大,就可以保留更多的語句,當然被共享的可能性也就越大了。當向oracle提交乙個sql語句時,oracle會首先在這塊記憶體中查詢相同的語句。 

sql共享的三個條件: 

1,當前被執行的語句和共享池中的語句必須完全相同 (包括大小寫、空格、換行等) 

2,兩個語句所指的物件必須完全相同 (同義詞與表是不同的物件) 

3,兩個sql語句中必須使用相同的名字的繫結變數(bind variables) 

oracle對兩者採取的是一種嚴格匹配策略,要達成共享。sql語句必須完全相同(包括空格、換行等)。能夠使用共享的語句必須滿足三個條件: 

www.2cto.com  

① 字元級的比較。當前被執行的語句和共享池中的語句必須完全相同。 

例如:  select * from atable;和下面每乙個sql語句都不同: 

select  *from atable 

select  *  from atable; 

② 語句所指物件必須完全相同。即兩條sql語句操作的資料庫物件必須同一。 

③語句中必須使用相同命名的繫結變數。如:第一組的兩個sql語句是相同的,可以共享;而第二組中兩個語句不同,即使在執行時賦予不同的繫結變數以相同的值: 

● 第一組 select pin,name from people where pin =  :blk1.pin; 

select pin,name from people where pin =:blk1.pin; 

●第二組 select pin,name from people where pin =:blk1.ot_jnd; 

select pin,name from people where pin = :blk1.ov_jnd; 

sql parse與共享sql語句: 

當乙個oracle例項接收一條sql後 

1、create a cursor 建立游標 

2、parse the statement 分析語句 

3、describe results of a query 描述查詢的結果集 

4、define output of a query 定義查詢的輸出資料 

5、bind any variables 繫結變數 

6、parallelize the statement 並行執行語句 

7、run the statement 執行語句 

8、fetch rows of a query 取查詢出來的行 

9、close the cursor 關閉游標 

下面這個語句每執行一次就需要在share pool 硬解析一次,一百萬使用者就是一百萬次,消耗cpu和記憶體,如果業務量大,很可能導致宕庫…… 

如果繫結變數,則只需要硬解析一次,重複呼叫即可 

select * from dconmsg          

where contract_no = 32013484095139 

oracle 優化器模式: 

oracle的優化器共有3種模式:rule (基於規則)、cost(基於成本)、choose(基於選擇)。 

設定預設的優化器的方法,是在啟動引數檔案中針對optimizer_ mode引數的各種宣告進行選擇,如rule、cost、choose、all_ rows、first_ rows。當然也可以在sql語句級別或是會話級別對其進行覆蓋。 

為了使用基於成本的優化器(cbo,cost—based optimizer),必須經常執行analyze命令,以增加資料庫中的物件統計資訊(object statistics)的準確性。如果資料庫的優化器模式設定為基於選擇,那麼實際的優化器模式將和是否執行過analyze命令有關。如果資料表已經被analyze過,優化器模式將自動切換成cbo,反之,資料庫將採用rule形式的優化器。在預設情況下,oracle採用choose優化器。為避免那些不必要的全表掃瞄,必須盡量避免使用choose優化器,而直接採用基於規則或者基於成本的優化器。 

影響資料庫系統效能的要素: 

1,主機cpu,ram,儲存系統; 

2,os引數配置,oracle引數配置; 

3,應用方面:資料庫設計及sql程式設計的質量 

乙個效能優秀的應用系統需要: 

1,良好的硬體配置; 

2,正確合理的資料庫及中介軟體引數配置; 

3,合理的資料庫設計; 

4,良好的sql程式設計; 

5,執行期的效能優化 

sql tunning 的重點: 

sql: insert, update, delete, select(主要關注的是select) 

關注的是:如何用最小的硬體資源消耗、最少的響應時間定位資料位置 

sql優化的一般性原則: 

1,目標: 

減少伺服器資源消耗(主要是磁碟io); 

2,設計方面: 

盡量依賴oracle的優化器,並為其提供條件; 

合適的索引,索引的雙重效應,列的選擇性; 

3,編碼方面: 

利用索引,避免大表full table scan; 

合理使用臨時表; 

避免寫過於複雜的sql,不一定非要乙個sql解決問題; 

在不影響業務的前提下減小事務的粒度; 

優化概括: 

● 建立表的時候。應盡量建立主鍵,盡量根據實際需要調整資料表的pctfree和pctused引數;大資料表刪除,用truncate table代替delete。 

● 合理使用索引,在oltp應用中一張表的索引不要太多。資料重複量大的列不要建立二叉樹索引,可以採用位圖索引;組合索引的列順序盡量與查詢條件列順序保持一致;對於資料操作頻繁的表,索引需要定期重建,以減少失效的索引和碎片。 

● 查詢盡量用確定的列名,少用*號。select count(key)from tab where key> 0效能優於select count(*)from tab; 

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

盡量少巢狀子查詢,這種查詢會消耗大量的cpu資源;對於有比較多or運算的查詢,建議分成多個查詢,用union all聯結起來;多表查詢的查詢語句中,選擇最有效率的表名順序。oracle解析器對錶解析從右到左,所以記錄少的表放在右邊。 

● 盡量多用commit語句提交事務,可以及時釋放資源、解鎖、釋放日誌空間、減少管理花費;在頻繁的、效能要求比較高的資料操作中,盡量避免遠端訪問,如資料庫鏈等,訪問頻繁的表可以常駐記憶體:alter table...cache; 

● 在oracle中動態執行sql,盡量用execute方式,不用dbms_sql包。

ORACLE SQL效能優化(二)

4.選擇最有效率的表名順序 只在基於規則的優化器中有效 oracle的解析器按照從右到左的順序處理from子句中的表名,因此 from子句中寫在最後的表 基礎表 driving table 將被最先處理.在from子句中包含多個表的情況下,你必須選擇記錄條數最少的表作為基礎表.當oracle處理多個...

ORACLE SQL效能優化(三)

8.使用decode函式來減少處理時間 使用decode函式可以避免重複掃瞄相同記錄或重複連線相同的表.例如 select count sum sal from emp where dept no 0020 and ename like smith select count sum sal from...

Oracle SQL 效能優化技巧

sun2004發表於 2008 12 25 11 28 眾所周知,資料庫設計的好壞直接關係到資料庫執行的效率。根據筆者的經驗,對於提公升資料庫效能來說,合理的資料庫設計,比公升級伺服器的硬體配置,還要來的有效。但是,筆者無論是在跟同事合作,又或者是在論壇上跟相關同行交流的時候,總是會發現有些人有一些...