目錄
- 查看執行計劃
- 查看預估的執行計劃--AUTOTRACE
- 查看預估的執行計劃--EXPLAIN PLAN FOR
- 查看現在的真實執行計劃--SHARE POOL
- 查看過去的真實執行計劃--AWR
- 執行計劃分析
- 訪問路徑方法
- 表連接方式
- *謂詞過濾信息
- 執行計劃的訪問路徑
- 訪問路徑的基本類型
- 全表掃描(TABLE ACCESS FULL)
- 索引掃描
- 索引唯一掃描(INDEX UNIQUE SCAN)
- 索引範圍掃描(INDEX RANGE SCAN)
- 索引全掃描(INDEX FULL SCAN)
- 索引快速全掃描(INDEX FAST FULL SCAN)
- 索引跳躍式掃描(INDEX SKIP SCAN)
- 索引降序範圍掃描(INDEX RANGE SCAN DESCENDING)
- 執行計劃的控制
查看執行計劃
recursive calls :遞歸調用。一般原因:dictionary cache未命中;動態存儲擴展;PL/SQL語句
db block gets :bufer中讀取的block數量,用於insert,update,delete,selectfor update
consistent gets :這裏是一致讀次數(一個block可能會被讀多次),bufer中讀取的用於查詢(除掉select forupdate)的block數量。
--db blocksgets+consistent gets= logical read
physical reads :從磁盤上讀取的block數量
redo size :bytes,寫到redo logs的數據量
bytes sent via SQLNet to client
bytes received via SQLNet from client
SQL*Net roundtrips to/from client
sorts (memory) :內存排序次數
sorts (disk) :磁盤排序次數;與sort_area_size有關
官網對consistent gets 的解釋:
consistent gets:Number of times a consistent read wasrequested for a block.
通常我們執行SQL查詢時涉及的每一block都是Consistent Read, 只是有些CR(Consistent Read)需要使用undo 來進行構造, 大部分CR(Consistent Read)並不涉及到undo block的讀.
還有就是每次讀這個block都是一次CR(可能每個block上有多個數據row), 也就是如果某個block被讀了10次, 系統會記錄10個Consistent Read.
簡單的説:
consistentgets : 通過不帶for update的select 讀的blocks.
dbblock gets : 通過update/delete/selectfor update讀的blocks.
db block gets + consistent gets = 整個邏輯讀。
查看預估的執行計劃--AUTOTRACE
set autot on ----輸出所有內容,包括語句本身的查詢結果、執行計劃,以及性能統計數據
set autot on exp ----輸出所有內容,包括語句本身的查詢結果和執行計劃,不輸出性能統計數據
set autot on stat----輸出所有內容,包括語句本身的查詢結果和性能統計數據,不輸出執行計劃
set autot trace ----輸出執行計劃和性能統計數據,不輸出語句本身的查詢結果
set autot trace exp ----輸出執行計劃,不輸出語句本身的查詢結果和性能統計數據
set autot trace stat ----輸性能統計數據,不輸出語句本身的查詢結果和執行計劃
開啓autotrace我們可以看到目標SQL執行時所耗費的物理讀、邏輯讀、產生redo的數量及排序的數量等。
查看預估的執行計劃--EXPLAIN PLAN FOR
explain plan for select count(*) from t10;
select * from table(dbms_xplan.display);
plan_table(全局臨時表,它會存儲數據直到會話結束,多個併發用户可以互不影響彼此的工作) 、$ORACLE_HOME/rdbms/admin/utlxplan.sql
查看現在的真實執行計劃--SHARE POOL
v$sql_plan
v$sql_plan_statistics
v$sql_workarea
v$sql_plan_statistics_all
select count() from t10;
select sql_id,child_number,sql_text from v$sql where sql_text like '%select count() from t10%' and sql_text not like '%v$sql%';
select * from table(dbms_xplan.display_cursor('fu9fh7nx72xx8',0,'advanced'));
或
#特殊執行計劃
ALTER SESSION SET STATISTICS_LEVEL=ALL;
執行待分析的SQL
select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));
或
select * from table(dbms_xplan.display_cursor(null,null,'advanced')); --得到的信息更詳細
查看過去的真實執行計劃--AWR
查詢自動工作量資料庫(Automatic Workload Repository)或查詢Statspack表,它顯示存儲在資料庫中的執行計劃
dba_hist_sql_plan
select * from table(dbms_xplan.display_awr('gwq01ynnbm5aj'));
執行計劃分析
訪問路徑方法
表訪問操作:
TABLE ACCESS FULL #全表掃描,通過完全掃描的方式訪問表
TABLE ACCESS BY INDEX ROWID #通過由索引中獲取的ROWID訪問表
索引訪問操作:
INDEX FULL SCAN # 全索引掃描,即對索引進行完全掃描訪問
表連接方式
MERGE JOIN
要進行排序合併,必須有一個前提:兩邊數據集中數據都已經按照關聯字段排序,
否則,優化器會加上一個排序操作(SORT JOIN),使數據集按照關聯字段排序。
MERGE JOIN實現過程:從兩邊數據集的第一條記錄開始匹配,如果數值相同,則返回記錄;
如果外數據記錄中的數值小於內數據記錄,則外數據集的遊標向下移,讀取下一條記錄進行匹配;
否則,內數據集的遊標向下移,讀取下一條記錄進行匹配。
*謂詞過濾信息
執行計劃的訪問路徑
訪問路徑的基本類型
指的是ORACLE通過哪種方式去獲取數據,比如通過全表掃描,索引掃描,或者通過ROWID獲取數據
全表掃描(TABLE ACCESS FULL) 索引掃描
ROWID掃描
全表掃描(TABLE ACCESS FULL)
等待事件:db file scattered read
alter session set statistics_level=all; select count(*) from t1;
select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
索引掃描
索引唯一掃描(INDEX UNIQUE SCAN)
索引範圍掃描(INDEX RANGE SCAN)
索引全掃描(INDEX FULL SCAN)
索引快速全掃描(INDEX FAST FULL SCAN)
索引跳躍式掃描(INDEX SKIP SCAN)
索引降序範圍掃描(INDEX RANGE SCAN DESCENDING)
索引唯一掃描(INDEX UNIQUE SCAN)
等待事件:db file squential read
create unique index index_t1 on t1(id);
alter session set statistics_level=all;
select id,name from t1 where id=1; select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
索引範圍掃描(INDEX RANGE SCAN)
等待事件:db file squential read
alter session set statistics_level=all;
select id,name from t1 where id>=1 and id<=100; select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
HINT: INDEX(表名/別名 索引名)
索引全掃描(INDEX FULL SCAN)
等待事件:db file squential read
alter session set statistics_level=all;
select/*+ INDEX (t1 index_t1) */ id from t1 where id is not null;
select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
索引快速全掃描(INDEX FAST FULL SCAN)
等待事件:db file scattered read(多塊讀)
HINT:INDEX_FFS(表名/別名 索引名)
alter session set statistics_level=all;
select /*+ INDEX_FFS(t1 INDEX_T1) */ id from t1 where id is not null;
select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
索引跳躍式掃描(INDEX SKIP SCAN)
只可能發生在組合索引上,引導列沒有包含在where條件中,並且引導列基數很低
HINT: INDEX_SS(表名/別名 索引名)
create index index_id_name on t1(id,name);
Alter table t1 add (addr varchar2(10));
alter session set statistics_level=all;
select/*+ INDEX_SS(t1 index_id_name) */ * from t1 where NAME='gyj9992';
select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
索引降序範圍掃描(INDEX RANGE SCAN DESCENDING)
等待事件:db file squential read
HINT:INDEX_DESC(表名/別名 索引名)
alter session set statistics_level=all;
select /*+ index_desc(t1 index_t1) */id,name from t1 where id is not null order by id desc ;
select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
執行計劃的控制
加提示
穩固計劃
sql概要(sqlprofile) 改變統計信息
設置優化器模式相關的參數
基線(baseline)