基於成本的優化--CBO
阿新 • • 發佈:2018-02-25
優化 CBO SQL語句 執行計劃 選擇CBO的優化方式
默認條件下,CBO將SQL語句的吞吐量作為優化目標
三種不同的優化方式
ALL_ROWS :該優化方式是Oracle的默認模式,優化目標是實現查詢的最大吞吐量
FIRST_ROWS_n:該優化方式使用CBO的成本優化輸出查詢的前n行數據,目標是以滿足快速相應的查詢需求,
FIRST_ROWS :該方式是FIRST_ROWS_n優化方式的老版本,作用是使用CBO的成本優化盡快輸出查詢的前幾行數據,滿足最小相應時間的需求
查詢當前數據庫的CBO優化方式
show parameter optimizer_mode
在實例級設置優化方式
alter system set optimizer_mode = FIRST_ROWS_10 scope=spfile
在會話級設置優化方式
alter session set optimizer_mode=ALL_ROWS
會話級上設置優化方式必須使用hint提示
select /*+first_rows_10*/ ename,sal,mgr
from scott.emp
優化器工作過程
步驟
1.SQL轉換
在CBO優化中,一個SQL語句往往被轉換成另一種表達形式,這個轉換的基礎是CBO認為轉換後的查詢會更有效
2.確定訪問路徑
一個SQL查詢中對數據的訪問的路徑要根據訪問這些數據消耗的資源來判斷,在多個查詢路徑中選擇計算成本最小的一個。
3.確定聯結方式
在SQL語句中涉及多個表時,CBO會根據統計數據以及表的鍵的信息來選擇連接方式,在多個連接方法中選擇計算成本最低的一個作為最佳連接方法
4.確定聯結次序
CBO會對不同的連接次序中進行計算以選擇最好的執行計劃。
自動統計數據
查看GATHER_STATS_JOB狀態
select job_name,state,owner
from dba_scheduler_jobs;
通過數據字典DBA_TABLES查詢用戶SCOTT擁有表的統計分析情況
select last_analyzed,table_name,owner,num_rows,sample_size
from dba_tables
where owner='SCOTT'
手動統計數據庫數據
DBMS_STATS
存儲過程
GATHER_DATABASE_STATS 為全庫中的表統計數據
GATHER_SCHEMA_STATS 為某個模式統計數據
GATHER_TABLE_STATS 為某個特定的表統計數據
GATHER_INDEX_STATS 為某個索引表統計數據
上述統計數據保存在 DBA_TAB_STATISTICS 和 DBA_TAB_COL_STATISTICS
為模式SCOTT的所有表統計數據
execute DBMS_STATS.GATHER_SCHEMA_STATS(ownname=>'SCOTT');
驗證模式SCOTT的數據統計成功
select last_analyzed,table_name,owner,num_rows,sample_size
from dba_tables
where owner='SCOTT'
為模式SCOTT用戶的表EMP統計數據
execute DBMS_STATS.GATHER_TABLE_STATS('SCOTT','EMP');
為DEPT的索引統計數據
execute DBMS_STATS.GATHER_INDEX_STATS('SCOTT','PK_DEPT')
手工收集數據庫級別的統計數據-----需要對初始化參數JOB_QUEUE_PROCESSES設置一個非0值
execute DBMS_STATS.GATHER_DATABASE_STATS(estimate_percent=>null)
查詢表的統計數據 DBA_TAB_STATISTICS
查詢表的列的統計數據 DBA_TAB_COL_STATISTICS
統計OS數據
DBMS_STATS.GATHER_SYSTEM_STATS SYS.AUX_STAST$
無負載方式下收集10分鐘的系統統計數據
execute DBMS_STATS.GATHER_SYSTEM_STATS('NOWORKLOAD',10)
收集系統統計數據
execute DBMS_STATS.GATHER_SYSTEM_STATS('start')
execute DBMS_STATS.GATHER_SYSTEM_STATS('stop')
每三分鐘執行一次
查詢統計的系統數據
select * from SYS.AUX_STAST$;
手工統計字典數據---具備SYSDBA權限
收集固定字典表的統計數據
execute DBMS_STATS.GATHER_FIXED_OBJECTS_STATS;
收集數據字典表的統計數據
execute DBMS_STATS.GATHER_DIRECTORY_STATS;
/
使用過程GATHER_SCHEMA_STATS統計數據字典數據
execute DBMS_STATS.GATHER_SCHEMA_STATS('sys')
主動優化SQL語句
SQL語句優化工具
1.使用EXPLAN FOR 指令
utlxplan.sql
執行腳本---生成PLAN_TABLE表
@?/rdbms/admin/utlxplan.sql
通過EXPLAIN PLAN FOR 指令分析SQL語句的執行計劃
explain plan for select count(*) from scott.emp;
查看表 PLAN_TABLE 中SQL語句執行計劃信息
col if for 999
col operation for a20
col options for a20
col object_name for a20
select id,operation,options,object_name,position
from PLAN_TABLE
OPERATION :為TABLEACCESS說明該步驟的行為是訪問表
OPTIONS :為FULL,說明全表掃描訪問表
OBJECT_NAME :說明行為的對象為表EMP
使用AUTOTRACE指令------SQL_TRACE=TRUE
設置參數 SQL_TRACE 啟動SQL語句追蹤
alter system set SQL_TRACE = TRUE;
/* 選項 結果
SET AUTOTRACE ON 查詢輸出,解釋計劃,統計信息
SET AUTOTRACE OFF 關閉 AUTOTRACE
SET AUTOTRACE ON EXPLAIN 查詢輸出,解釋計劃,沒有統計信息
SET AUTOTRACE ON EXPLAIN STAT 查詢輸出,解釋計劃,統計信息
SET AUTOTRACE ON STAT 查詢輸出,解釋計劃,統計信息
SET AUTOTRACE TRACE 解釋計劃,統計信息,生成結果但不顯示
SET AUTOTRACE TRACE EXPLAIN 只有解釋計劃,不生成結果
SET AUTOTRACE TRACE STAT 只有統計,生成結果但不顯示*/
使用AUTOTRACE追蹤SQL語句執行計劃
set autotrace traceonly
select count(*) from scott.emp
recursive calls 遞歸調用的次數 db block gets 讀數據塊的數量 consistent gets 總的邏輯I/O physical reads 物理I/O redo size 重做數量 bytes sent via SQL*Net to client SQL*Net通信 bytes received via SQL*Net from client SQL*Net roundtrips to/from client sorts (memory) 內存排序統計 sorts (disk) 磁盤排序統計 rows processed 被檢索的行數 關閉AUTOTRACE set autotrace OFF 啟動 SQL Trace的前提 1.statistics_level: TYPICAL / ALL BASE 2.timed_statistics: TRUE -----BASE False -----TYPICAL / ALL 3.user_dump_dest: 該參數存儲SQL語句的追蹤文件。 (max_dump_file_size) 啟動SQL Trace追蹤 實例級啟動SQL Trace追蹤 alter system set SQL_TRACE=TRUE 會話級啟動SQL Trace追蹤 alter session set SQL_TRACE=TRUE / begin sys.dbms_session.set_sql_trace(TRUE); end; 使用 TKPPOF 解釋 SQL Trace文件 執行sql查詢 使用TKPPOF工具格式化SQL追蹤文件 TKPPOF xxxxxxxx.trc xxxx.txt sys=no 格式化參數的含義 count :不同執行階段所讀取的數據塊數量 cpu :不同執行階段鎖消耗的CPU時間,單位是秒 elapsed :執行用掉的時間 disk :物理磁盤數據讀操作數目 query :一致的緩沖區讀取數量 current :數據庫塊讀取的數量 call :該參數說明SQL語句的不同執行階段
消除子查詢優化SQL語句 對查詢用戶scott的emp表進行嵌套子查詢 select * from scott.emp e1 where e1.sal> (select avg(sal) from scott.emp e2 where e2.deptno=e1.deptno) 開啟AUTOTRACE功能 set autotrace traceonly 跟蹤SQL語句的執行 select * from scott.emp e1 where e1.sal> (select avg(sal) from scott.emp e2 where e2.deptno=e1.deptno)
跟蹤改寫的SQL語句 使用聯機視圖改寫子查詢 select * from scott.emp e1,(select e2.deptno deptno ,avg(e2.sal) avg_sal from scott.emp e2 group by deptno ) dept_avg_sal where e1.deptno = dept_avg_sal.deptno and e1.sal > dept_avg_sal.avg_sal
被動優化SQL語句 使用分區表 使用表和索引壓縮 創建壓縮表 create table compress_emp compress tablespace users as select * from scott.emp 查詢是否成功創建壓縮表 compress_emp select table_name,tablespace_name,compression from user_tables where table_name like 'COMPRESS%'; 創建壓縮索引 create index compress_emp_ename_idx on compress_emp(ename) compress; 保持CBO的穩定性 1.創建存儲大綱的前提 初始化參數 QUERY_REWRITE_ENABLED = TRUE STAR_TRANSFORMATION_ENABLED = TRUE 驗證系統師傅具備創建存儲大綱的前提 show paameter QUERY_REWRITE_ENABLED; show paramter STAR_TRANSFORMATION_ENABLED; show parameter optimizer_features_enable; 2.創建存儲大綱 創建數據庫級的存儲大綱 alter system set create_stored_outlines = TRUE 創建會話級的存儲大綱 alter session set create_stored_outlines = TRUE 為特定SQL語句創建存儲大綱 create outline emp_outline on select * from scott.emp tablespace oltbs; 查詢EMP_OUTLINE創建信息 select ol_name,sql_text,creator,timestamp from ol$ where ol_name like 'EMP%' 查詢Oracle自動生產的存儲大綱的名字 set lines 120 select ol_name,sql_text from ol$ 3.刪除存儲大綱 刪除存儲大綱-----sysdba drop outline emp_outline 4.啟用存儲大綱 修改參數 USE_STORED_OUTLINES 為TRUE alter system set USE_STORED_OUTLINES= TRUE
基於成本的優化--CBO