一準備工做
1.1 取tracefile的幾種辦法(11g): ios
select tracefile ,s.module from v$process p,v$session s where s.paddr=p.addr and s.username='TEST' and module ='SQL*Plus' SELECT value FROM v$diag_info WHERE name='Default Trace File';
2 生成10053sql
alter session set events '10053 trace name context forever'; exec dbms_system.set_ev(sid,serial#,10053,8,'test');
或者經過sql_Idexecute DBMS_SQLDIAG.DUMP_TRACE(p_sql_id=>'5s4ny8pxtdkyf', p_child_number=>0, p_component=>'Optimizer', p_file_id=>'SQL_TRACE_10053');
3 執行sql,關閉tracesession
select * from T_KINGDEE_CONSUME_DAY; alter session set events '10053 trace name context off';
二 解析
oracle成本的計算公式以下:
Cost = (
#SRds sreadtim +
#MRds mreadtim +
CPUCycles / cpuspeed
) / sreadtime
簡化爲:
cost=#srds + #mrds * mreadtim/sreadtim + #cpucycles/(cpuspped*sreadtim)
#SRds - number of single block reads 單塊讀的次數
#MRds - number of multi block reads 多塊讀的次數
#CPUCyles - number of CPU cycles 一個CPU週期
sreadtim - single block read time 讀取單個數據塊的平均時間
mreadtim - multi block read time 讀取多個數據塊的平均時間
cpuspeed - CPU cycles per second CPU週期/秒
數據來源:
來源:
select * from sys.aux_stats$
參數解釋
FLAGS:標誌
CPUSPEEDNW:非工做量統計模式下CPU主頻,直接來自硬件
IOSEEKTIM:IO尋址時間(毫秒),直接來自硬件
IOTFRSPEED:IO傳輸速率(字節/毫秒)
SREADTIM:讀取單個數據塊的平均時間
MREADTIM:讀取多個數據塊的平均時間
CPUSPEED:工做量統計模式下CPU主頻,根據當前工做量評估出一個合理值
MBRC:oracle收集完統計信息後評估出的一次多塊讀能夠讀幾個數據塊,不設置值其爲8
MAXTHR:最大IO吞吐量(字節/秒)
SLAVETHR:平均IO吞吐量(字節/秒)
查看trace文件部分:oracle
SYSTEM STATISTICS INFORMATION
Using NOWORKLOAD Stats
CPUSPEEDNW: 3074 millions instructions/sec (default is 100)
IOTFRSPEED: 4096 bytes per millisecond (default is 4096)
IOSEEKTIM: 10 milliseconds (default is 10)
MBRC: NO VALUE blocks (default is 8)ide
MBRC:這裏在11g裏安裝完成後不設置顯示爲128,但在作10053發現其仍是爲8;
我這裏計算爲:
sreadtim=ioseektim+db_block_size/IOTFRSPEED=10+8192/4096=12
mreadtim=ioseektim+mbrc*db_block_size/IOTFRSPEED=10+8*8/4=26
查看trace文件:code
BASE STATISTICAL INFORMATION
Table Stats::
Table: T_KINGDEE_CONSUME_DAY Alias: T_KINGDEE_CONSUME_DAY
#Rows: 377547 #Blks: 2656 AvgRowLen: 40.00 ChainCnt: 0.00
Index Stats::
Index: IX_KINGDEE_CONSUME_DAY_N1 Col#: 2
LVLS: 2 #LB: 3743 #DK: 951 LB/K: 3.00 DB/K: 397.00 CLUF: 377547.00
Index: PK_T_KINGDEE_CONSUME_DAY Col#: 1 2
LVLS: 2 #LB: 2228 #DK: 377547 LB/K: 1.00 DB/K: 1.00 CLUF: 2979.00
Access path analysis for T_KINGDEE_CONSUME_DAYcomponent
io_cost=#mrds*mreadtim/sreadtime=round(2656/8)*26/12=719hash
計算cpu_costit
explain plan for select * from T_KINGDEE_CONSUME_DAY; select * from table(dbms_xplan.display()); select cpu_cost from plan_table; CPU_COST ------ 135954115
cpu_cost=135954115/(3074*12)/1000=3.68
總體cost=io_cost+cpu_cost=719+3.7=722.7
查看trace文件部分:io
SINGLE TABLE ACCESS PATH
Single Table Cardinality Estimation for T_KINGDEE_CONSUME_DAY[T_KINGDEE_CONSUME_DAY]
Table: T_KINGDEE_CONSUME_DAY Alias: T_KINGDEE_CONSUME_DAY
Card: Original: 377547.000000 Rounded: 377547 Computed: 377547.00 Non Adjusted: 377547.00
Access Path: TableScan
Cost: 724.69 Resp: 724.69 Degree: 0
Cost_io: 721.00 Cost_cpu: 135954115
Resp_io: 721.00 Resp_cpu: 135954115
Best:: AccessPath: TableScan
Cost: 724.69 Degree: 1 Resp: 724.69 Card: 377547.00 Bytes: 0
調整mbrc
SQL> alter system set db_file_multiblock_read_count=64 scope=both;
查看trace:
SYSTEM STATISTICS INFORMATION
Using NOWORKLOAD Stats
CPUSPEEDNW: 3074 millions instructions/sec (default is 100)
IOTFRSPEED: 4096 bytes per millisecond (default is 4096)
IOSEEKTIM: 10 milliseconds (default is 10)
MBRC: NO VALUE blocks (default is 64)
再次計算成本:
sreadtim=ioseektim+db_block_size/IOTFRSPEED=10+8192/4096=12
mreadtim=ioseektim+dbfilemultiblockreadcount * dbblocksize/IOTFRSPEED=10+64 * 8/4=138
io_cost=#mrds*mreadtim/sreadtime=round(2656/64,2)*138/12=477.25
cpu cost未變;
cost=io_cost+cpu_cost=3.68+477.25=480.93
沒調整db_file_multiblock_read_count以前爲721,調整後降低不少;
查看10053結果:
Access path analysis for T_KINGDEE_CONSUME_DAY
SINGLE TABLE ACCESS PATH
Single Table Cardinality Estimation for T_KINGDEE_CONSUME_DAY[T_KINGDEE_CONSUME_DAY]
Table: T_KINGDEE_CONSUME_DAY Alias: T_KINGDEE_CONSUME_DAY
Card: Original: 377547.000000 Rounded: 377547 Computed: 377547.00 Non Adjusted: 377547.00
Access Path: TableScan
Cost: 482.69 Resp: 482.69 Degree: 0
Cost_io: 479.00 Cost_cpu: 135954115
Resp_io: 479.00 Resp_cpu: 135954115
Best:: AccessPath: TableScan
Cost: 482.69 Degree: 1 Resp: 482.69 Card: 377547.00 Bytes: 0s
查看explain結果:
PLAN_TABLE_OUTPUT -------------------------------------------------------------- Plan hash value: 873558201 ---------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 377K| 14M| 483 (1)| 00:00:06 | | 1 | TABLE ACCESS FULL| T_KINGDEE_CONSUME_DAY | 377K| 14M| 483 (1)| 00:00:06 |
發現差一點,483-482,但這裏計算的比trace裏的差1位,這個差距由參數_table_scan_cost_plus_one控制;
檢查參數:
SELECT x.ksppinm NAME, y.ksppstvl VALUE, x.ksppdesc describ FROM x$ksppi x,x$ksppcv y WHERE x.inst_id = USERENV ('Instance') AND y.inst_id = USERENV ('Instance') AND x.indx = y.indx AND x.ksppinm LIKE '%_table_scan_cost_plus_one%';
禁用alter session set "_table_scan_cost_plus_one"=false;
再次查看執行計劃:
Plan hash value: 873558201 ------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 377K| 14M| 482 (1)| 00:00:06 | | 1 | TABLE ACCESS FULL| T_KINGDEE_CONSUME_DAY | 377K| 14M| 482 (1)| 00:00:06 | -------------------------------------------------------------------------------------------
再次調整_table_scan_cost_plus_one爲false,後由483降爲482;結論:db_file_multiblock_read_count這參數會影響你cost(%cpu)的整個結果;