oracle效能調優-**《oracle database 11g資料庫管理藝術》第19章(改進資料庫i你能:sql查詢優化)
效能調優是dba花費時間最多的乙個領域,主要包括:編寫高效的sql語句、分配合適的計算資源,
以及分析系統中的等待事件和資源爭用情況。
oracle建議在設計資料庫時遵循以下步驟:
1. 正確地設計應用程式;(應用程式最初階段就考慮效能調優為『主動調優』,反之為『被動調優』)
2. 調優應用程式的sql**;
3. 調優記憶體;
4. 調優io;
5. 調優爭用和其他問題;
使用者的sql語句要經歷語法分析、優化和執行階段。
1. 語法分析:主要包括檢查sql語句的語法和語義,最終結果是建立乙個語法分析樹。
2. 優化:基於成本的優化程式cbo,分為查詢重寫階段和物理執行計畫生成階段。
查詢重寫階段--語法分析樹被轉換為乙個抽象的邏輯查詢計畫。
執行計畫生成階段--將邏輯查詢計畫轉為乙個物理查詢計畫。
成本優化例子
select * from employee e, dept d where e.dept_no=d.dept_no and(e.job='supervisor' and d.city='dallas')
說明1:使用者每次只能讀寫一行資料,行級別(實際可能是塊級別)
說明2:資料庫將每個中間步驟都寫到磁碟上(實際可能不是)
說明3:表上沒有索引
說明4:employee表2000行,dept表40行(管理人的數量也是40-每個部門1個)
說明5:有10個部門在dallas
查詢1:笛卡爾聯結,雇員表和部門表構成乙個笛卡兒積,在這個笛卡兒積上看看有多少行滿足需求。
成本評估:
(1)雇員表和部門表的笛卡兒積需要對兩個表進行讀取的次數:2000 + 40 = 2040讀
(2)建立笛卡兒積:2000 * 40 = 80000寫
(3)讀取笛卡兒積並與選擇條件相比較:2000 * 40 = 80000讀
(4)合計io成本:2040 + 80000 + 80000 = 162040
查詢2:兩個表的聯結,先在dept_no列上對雇員表和部門表進行聯結操作,再選擇滿足條件的行。
成本評估:
(1)聯結雇員表和部門表首先需要對兩個表的所有行進行讀取:2000 + 40 = 2040讀
(2)建立雇員表和部門表的聯結:2000寫
(3)讀取聯結結果花費:2000讀
(4)合計io成本:2040 + 2000 + 2000 = 6040
查詢3:簡化關係的聯結,先讀取雇員表以獲取所有的管理人行,然後讀取部門表得到所有dallas部門,
最後,對從雇員表和部門表中的到的結果進行聯結。
成本評估:
(1)讀取雇員表得到管理人行:2000讀
(2)寫上個步驟中得到的管理人行:40寫
(3)從部門表得到所有的dallas部門:40讀
(4)寫上個步驟中得到的dallas部門:10寫
(5)聯結從該查詢前面步驟得到的管理人行和部門行:總計40 + 10 = 50寫
(6)從前一步中讀取聯結結果:50讀
(7)合計io成本:2000 + 40 + 40 + 10 + 50 + 50 = 2190
例子總結:說明笛卡兒積要比多數約束性聯結的成本都高。
查詢處理的啟發式策略:
1. 盡早執行選擇操作,這樣就可以在操作的早期階段消除多數的笛卡爾行。如果在最後階段還保留
大多數記錄,就會與遲早要去除的記錄進行很多不必要的比較。
2. 盡早執行投影操作,以限制要處理的列的數目
3. 如果需要執行連續的聯結操作,首先執行較小的聯結
4. 計算一次公共表示式,並儲存其結果
oracle的舊版本中,可以在基於規則的和基於成本的優化程式之間進行選擇。
cbo方法差不多總是要比老的、基於規則的方法執行的要快。
基於規則的優化程式是乙個即將淘汰的產品。
為優化程式提供資料統計:預設下,每晚或週末,oracle 11g存在乙個名為gather_starts_job的作業
在執行,監控全部資料庫物件的所有dml更改,如insert、update和delete,可以在dba_tab_modifications
檢視中檢視這些更改資訊,根據該監控oracle決定是否要為物件收集新的統計資料。
1. 檢查gather_stats_job是否在收集統計資料:
select last_analyzed, table_name, owner, num_rows, sample_size
from dba_tables
where last_analyzed is not null
and table_name = 'your table name'
order by last_analyzed desc
2. 檢視列的統計資料:
select column_name, num_distinct from dba_tab_col_statistics where table_name='your table name'
設定優化程式方式
1. all_rows: 預設的優化程式方式,不管是否有查詢中的每個表的統計資料,該方式都命令oracle使用cbo,
以實現最大吞吐量這個明確目標。
2. first_rows_n: 此優化方式不管統計資料是否可用都使用成本優化,目的是使輸出前n行的響應時間最快。
3. first_rows:使用成本優化和某種試探法(經驗規則),而無論是否有統計資料。
了解資料庫當前的優化程式方式:select name, value from v$parameter where name = 'optimizer_mode'
優化程式做些什麼
1. sql轉換,oracle幾乎不會以原始形式來執行查詢。如果cbo確定另乙個sql表達形式可以更有效的得到同樣
的查詢結果,那麼在執行該查詢之前就會轉換該語句。
典型例子:具有or條件的查詢,cbo將其轉化為乙個使用union或union all的語句
(1)將in轉換為or語句;
(2)將or轉換為union或union all語句;
(3)將非直接相關的巢狀的選擇語句轉換為更有效的聯結(join);
(4)將外聯結轉換為更有效的內聯結(inner join);
(5)將複雜的子查詢轉為聯結、半聯結和反聯結(antijoin);
(6)對基於星型模式(star schema)的資料倉儲表進行星型轉換;
(7)將between轉換為大於等於或小於等於語句;
2. 選擇訪問路徑,通過不同的路徑訪問相同的資料。對每個查詢評估所有可用途徑並選取資源消耗最少的
優化程式在確定執行路徑前要經過的步驟:
(1)全表掃瞄:順序地讀取表中每個塊,但是對於大表,全表掃瞄效率通常不高;
(2)通過rowid對錶進行訪問:這是oracle中檢索行最快的方式;
(3)索引掃瞄:索引儲存兩種東西(索引列的列值和表中包含該列值的行的rowid);
3. 選擇聯結方式,當訪問兩個或多個表時,oracle根據共同的列來聯結這些表。
cbo使用的一些常見的聯結方法:
(1)巢狀迴圈聯結(nested-loop join):指定一表為驅動表(外部表),另一表為內部表,對驅動表中
每行資料都要讀取內部表的所有行。
(2)雜湊聯結(hash join):用其中較小的表在聯結鍵上構建乙個雜湊表,然後對大的表進行搜尋,並
從雜湊表中返回被聯結的行。
(3)分類合併聯結(sort-merge join):將聯結鍵上的輸入值分類,將已分類的列表進行合併。
4. 選擇聯結次序
資料庫SQL效能優化
如果訪問量巨大,除了sql優化外,還會涉及到分庫分表 讀寫分離 利用資料庫中介軟體來解決 1.對查詢進行優化,要盡量避免全表掃瞄,首先應考慮在 where 及 order by 涉及的列上建立索引。2.應盡量避免在 where 子句中對字段進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表...
資料庫SQL效能查詢
作為乙個開發 測試人員,或多或少都得和資料庫打交道,而對資料庫的操作歸根到底都是sql語句,所有操作到最後都是運算元據,那麼對sql效能的掌控又成了我們工作中一件非常重要的工作。下面簡單介紹下一些檢視oracle效能的一些實用方法 1 查詢每台機器的連線數 select t.machine,coun...
資料庫sql查詢優化
1.對查詢進行優化,要盡量避免全表掃瞄,首先應考慮在 where 及 order by 涉及的列上建立索引。2.應盡量避免在 where 子句中對字段進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃瞄,如 select id from t where num is null 最好不要給...