目錄

  • 查看執行計劃
  • 查看預估的執行計劃--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 SQL
Net 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實現過程:從兩邊數據集的第一條記錄開始匹配,如果數值相同,則返回記錄;
如果外數據記錄中的數值小於內數據記錄,則外數據集的遊標向下移,讀取下一條記錄進行匹配;
否則,內數據集的遊標向下移,讀取下一條記錄進行匹配。

*謂詞過濾信息

QItemWidget data用法_執行計劃

執行計劃的訪問路徑

訪問路徑的基本類型

指的是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)