改進資料庫效能 SQL查詢優化(1)

2021-10-24 01:15:36 字數 3827 閱讀 4445

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 最好不要給...