12条语句学会oracle cbo计算(二)

12条语句学会oracle cbo计算(二)
工作中,你可能会遇到统计数据正确,但就是不走你想要的执行计划的情况,最后一般通过hint或sql_profile解决.一条sql语句的性能主要依赖于好的物理结构,准确的系统统计数据,准确的对象统计数据,合理的查询优化器参数,合理的系统参数.这些因素也就是cost计算基本参数.因此产生的sql优化技术有很多,大概包含:改变访问结构,修改sql语句,加hint,改变执行环境,sql profile,stored outlines,sql plan baseline.其实无外乎就是通过调整sql适应环境或者通过调整环境适应sql.如果清楚Cost值的算法,就可以通过算法的对比,找到问题的真正原因,更有针对性的去解决问题.
全文主要参考Jonathan Lewis的<<基于成本的Oracle优化法则>>和黄玮(fuyuncat)的<<Oracle高性能SQL引擎剖析-SQL优化与调优机制详解>>,特别黄玮(fuyuncat)的这本,是非常值得去学习的.

准备用14篇来描述完,前2篇是统计数据,算法公式说明,后12篇用12条语句分别去套用说明.
本篇是cpu代价模型下cost算法公式说明:
COST=IOCOST+CPUCOST
CPUCOST = #CPUCYCLES/(CPUSPEED*SREADTIM)
Bytes =Rows*AVG_ROW_LEN
Time =CEIL(COST*SREADTIM/1000)

以下主要是关于Rows和IOCOST的算法公式.
--公式前端的(xxx)编号用于在后12篇中引用时标记
--由于CBO算法各版本变动很大,所以可能有误
1.基础数据来源
(1)NDV=dba_tab_co1umns.num_distinct
(2)DENS=dba_tab_co1umns.DENSITY
(3)ALLROWS=dba_tab1es.NUM_ROWS
(4)HIGHVAL=dba_tab_co1umns.HIGH_VALUE
(5)LOWVAL=dba_tab_co1umns.LOW_VALUE
(6)COLNB=dba_tab_co1umns.NULLABLE
(7)ACL=dba_tab_co1umns.AVG_COL_LEN
(8)ARL=dba_tab_co1umns.AVG_ROW_LEN

(9)OPTICA=优化器系统参数optimizer_index_cost_adj
(10)PPCT=优化器系统参数_optimizer_percent_parallel
(11)MBRC=优化器系统参数_db_fi1e_optimizer_read_count
(12)SAMINIO=优化器系统参数_smm_auto_min_io_size*1024
(13)SAMAXIO=优化器系统参数_smm_auto_max_io_size*1024
(14)OPTBLKSIZE=优化器系统参数_optimizer_b1ock_size
(15)SMPXMAX=优化器系统参数_smm_px_max_size
(16)MBDRC=SAMINIO/OPTBLKSIZE
(17)DOP=并行度
负载模式(NOWORKLOAD):
    (18)CPUSPEED=系统统计数据CPUSPEED
    (19)SREADTIM=系统统计数据SREADTIM
    (20)MREADTIM=系统统计数据MREADTIM
无负载模式(WORKLOAD):
    (21)CPUSPEED=系统统计数据CPUSPEEDNW
    (22)IOTFRSPEED=系统统计数据IOTFRSPEED
    (23)IOSEEKTIM=系统统计数据IOSEEKTIM
    (24)SREADTIM = IOSEEKTIM + OPTBLKSIZ/IOTFRSPEED
    (25)MREADTIM = IOSEEKTIM + MBRC * OPTBLKSIZ/IOTFRSPEED

workarea_size_po1icy=auto时
    (26)SAMSIZE=优化器系统参数_smm_max_size*1024=58720256
    (27)SASIZE=优化器系统参数_smm_min_size*1024=292864
workarea_size_po1icy=manua1时
    (28)SAMSIZE=优化器系统参数sort_area_size

2.单表单条件选择率
--以下选择的率的计算,都是条件中的值在范围内的情况下;值不在范围内的,会根据偏离的程度而递减.
a.条件值为常量或绑定变量有值,无直方图
(29)=的选择率为: GREATHST(1/NDV,DENS)*DECODE(COLNB= Y,1,NNV/ALLROWS)
(30)<>,!= 的选择率为: 1- GREATEST(1/NDV,DENS)*DECODH(COLNB= Y,1 ,NNV/ALLROWS)
(31)>,<,LIKE的选择率为: (BVAL- LOWVAL)/(HIGHVAL- LOWVAL)*DECODE(COLNB=Y,1,NNV/ALLROWS)
(32)<=,>= 的选择率为: ((BVAL- LOWVAL)/(HIGHVAL- LOWVAL)*DECODE+1/NNV)(COLNB=Y,1,NNV/ALLROWS)
(33)NOT LIKE 的选择率为: 1-GRHATEST(1/20,1/NDV,DENS)*DECODE(COLNB= Y,1 ,NNV/ALLROWS)
(34)IN    的选择率为: INNUM*GREATEST(1 /NDV,DENS)*DECODE(COLNB= Y,1 ,NNV/ALLROWS)
(35)NOT LIKE的选择率为:    1-(BVAL-LOWVAL)/(HTGHVAL-LOWVAT.)*DECODE(COLNB=Y,1,NNV/ALLROWS)
(36)BETWEEN AND    的选择率为: (BVAL[h]-BVAL[1])/(HIGHVAL-LOWVAL)*DECODE(COLNB=Y,1,NNV/ALLROWS)

b.绑定变量无值,无直方图
(37)= 的选择率为:GREATHST(1/NDV,DENS)*DECODE(COLNB= Y,1,NNV/ALLROWS)
(38)<>,!=的选择率为: 1- GREATEST(1/NDV,DENS)*DECODH(COLNB= Y,1 ,NNV/ALLROWS)
(39)>,<,LIKE的选择率为: GREATEST(I/20,1/NDV,DENS)*DECODE(COLNB- Y,1,NNV/ALLROWS)
(40)<=,>=的选择率为: (GREATEST(I/20,1/NDV,DENS)+1/NNV)*DECODE(COLNB- Y,1,NNV/ALLROWS)
(41)NOT LIKE的选择率为: 1-GRHATEST(1/20,1/NDV,DENS)*DECODE(COLNB- Y,1,NNV/ALLROWS)
(42)IN    的选择率为:INNUM*GREATEST(1 /NDVf DENS)*DECODE(COLNB= Y,1 ,NNV/ALLROWS)
(43)NOT IN    的选择率为:(1-GREATEST(1/NDV,DHNS)*DHCODH(COLNB= Y,1,NNV/ALLROWS))^INNUM
(44)BETWEEN AND    的选择率为:GREATEST(1/20,1/NDV,DENS)*DECODE(COLNB= Y,1,NNV/ALLROWS))^2

c.频率柱状图选择率
(45)=    的选择率为:(BEN[n]-BEN[n- 1 ])/MAXBEN*DECODE(COLNB= Y,1 ,NNV/ALLROWS)
(46)<>,!=    的选择率为:1- ( BEN[n]-BEN[n- 1 ])/MAXBEN*DHCODE(COLNB= Y,1,NNV/ALLROWS)
(47)<    的选择率为:(BEN[n- 1 ]+0.5)/MAXBEN*DECODE(COLNB= Y,1 ,NNV/ALLROWS)
(48)<=    的选择率为:(BEN[n]+0.5)/MAXBEN*DECODE(COLNB=Y,1 ,NNV/ALLROWS)
(49)>    的选择率为:1 ~(BEN[n]+0.5)/MAXBEN*DECODE(COLNB= Y,1 ,NNV/ALLROWS)
(50)>=    的选择率为:1-(BEN[n- 1 ]+0.5)/MAXBEN*DECODE(COLNB= Y,1,NNV/ALLROWS)
(51)LIKE 的选择率为:    (DBEN[1]+DBEN[2]+...+DBHN[i])/MAXBEN*DECODE(COLNB= Y,1,NNV/ALLROWS)
(52)NOT LIKE    的选择率为:1-(DBEN[1 ]+DBENt2]+...+DBEN[i])/MAXBEN*DHCODE(COLNB= Y,1,NNV/ALLROWS)
(53)IN    的选择率为:(DBHN[1 ]+DBEN[2]+...+DBHN[i])/MAXBHN*DHCODH(COLNB= Y,1 ,NNV/ALLROWS)
(54)NOT IN    的选择率为:1-(DBHN[1 ]+DBHN[2]+...+DBHN[i])/MAXBEN*DECODE(COLNB= Y,1,(NNV/ALLROWS)
(55)BETWEEN AND 的选择率为:(BEN[h]~BHN[1])/MAXBEN*DECODH(COLNB= Y,1 ,NNV/ALLROWS)

d.高平衡柱状图选择率
(56)=    的选择率为:DECODE(BEN[n]-BEN[n- 1] > i ,(BEN[n BEN[n- 1])/BKTNUM,GREATEST(1 /NDV,DENS))*DECODE(COLNB= Y,1 ,NNV/ALLROWS)
(57)<>,!=的选择率为:    1 - DECODE(BEN[n]-BEN[n- 1 ]>1 ,(BEN[n] -BEN[n—1])/BKTNUM,GREATEST(1/NDV,DENS))*DFCODE(COLNB- Y,1 ,NNV/ALLROWS)
(58)<    的选择率为:(BEN [n- 1 ]+POPADJ+ RANGEADJ)/BKTNUM * DECODE(COLNB= Y,1 ,NNV /ALLROWS)
(59)<=的选择率为:    (BEN[n]+POPADJ+ RANGEADJ)/BKTNUM*DECODE(COLNB= Y,1 ,NNV/ALLROWS)
(60)>    的选择率为:1 -(BEN [n ]+POPADJ+ RAN GEADJ)/BKTNUM *DECODH(COLNB= Y,1 ,NNV/ALLROWS)
(61)>=的选择率为:    1 -(BEN[n- 1 ]+POPADJ+ RANGEADJ)/BKTNUM*DECODE(COLNB* Y,1 ,NNV/ALLROWS)
(62)IN的选择率为:    EQOPSEL[1 ]+EQOPSEL[2]+...+EQOPSEL[i]
(63)NOT IN    的选择率为:1-EQOPSEL[1]+EQOPSEL[2]+...+EQOPSEL[i]
(64)BETWEEN AND,LIKE的选择率为:    BEN[h]-BEN[1]+POPADJ+ RANGEADJ)/BKTNUM*DECODE(COLNB= Y,1 ,NNV/ALLROWS)
(65)NOT LIKE的选择率为:    1-(BEN[h]~BEN[1]+POPADJ+ RANGEADJ)/BKTNUM*DECODE(COLNB= Y,1 ,NNV/ALLROWS)

3.单表多条件过滤组合的选择率
(66)A AND B    的选择率为:OPSEL[a] * OPSEL[b]
(67)A OR B    的选择率为:OPSEL[a] + OPSEL[b]- OPSEL[a]OPSEL[b]
(68)NOT A    的选择率为:1-OPSEL[a]

4.两表关联选择率
(69)JOINSEL= LEASTEST(COLSEL[Outer], COLSEL[Inner])
(70)CARD[Join] = CARD[Outer]*CARD[Inner]*JOINSEL

5.单表多数据块读操作代价计算
负载模式(NOWORKLOAD):
(71)IOCOST = (#BLKS/MBRC)*MREADTIM/SREADTIM
无负载模式(WORKLOAD):
(72)IOCOST = (#BLKS/MBRC)*(IOSEEKTIM + MBRC*OPTBLKSIZE/IOTFRSPEED)/(IOSEEKTIM+OPTBLKSIZE/IOTFRSPEED)
(73)CPUCOST = #CPUCYCLES /(CPUSPEED*SREADTIM)

6.单表单数据块读操作代价计算
(1)IOCOST = SRDCOST = #SRDS
索引范围扫描
(74)#SRDS = RBBLKS + RLBLKS
(75)RBBLKS = BLVL
(76)RLBLKS = CEIL(LBLKS*INDACCSEL)
(77)IOCOST = ROUND((BLVL + CEIL(LBLKS*INDACCSEL) * OPTICA/100)
索引唯一扫描
(78)IOCOST = BLVL
由索引ROWID访问表
(79)IOCOST=ROUND((BLVL + CEIL(LBLKS*INDACCSEL) +CEIL(CLUF*INDFLTSEL))*OPTICA/100)

7.单表排序操作代价计算
(80)SDSIZE = SROWNUM*SROWSIZE
(81)RROWSIZE = LEAST(AVGRLEN, SUM(ACL1~n))
(82)SROWSIZE = RROWSIZE + 10 + CEIL(RROWSIZE/10)
(83)如果SDSIZE > SASIZE,说明排序需要写入磁盘,否则IOCOST[Sort]=0
(84)SORTWIDTH = FLOOR((SAMSIZE-((60*SAMSIZE/1024/320-40*(SAMSIZE/1024/320-1))+LOG(2,MBDRC)*80)*1024)/((SAMINIO+OPTBLKSIZE)*2.5))
(85)INTRUNS = GREATEST(CEIL(SDSIZE/SAMSIZE), 2)
(86)MERGES = CEIL(LOG(SORTWIDTH,INIRUNS))
(87)SORTBLKS = CEIL(SDSIZE/(OPTBLKSIZE-24)
(88)PASSIO = CEIL(SORTBLKS*(MBDRC*MREADTIM/SREADTIM)/(MBDRC+1 )/(MBRC-1 ))*2 + CEIL(S0RTBLKS*(MBRC-1-MBDRC)/(MBDRC+1)/(MBRC-1))*2
(89)IOCOST[Sort]= SORTBLKS + (PASSIO * MERGES))

8.两表关联代价计算
a.嵌套循环关联代价计算
(90)IOCOST[NLJ] = IOCOST[Outer] + CARD[Outer]* IOCOST[Inner]

b.排序合并关联代价计算
(91)IOCOST[SMJ]= IOCOST[Outer] + IOCOST[Inner]

c.哈希关联代价计算
(92)SACL[Outer]= ACL[OuterColl]+...ACL[OuterColn]
(93)SACL[Inner]= ACL[InnerColl]+...ACL[InnerColn]
(94)HSIZE[Outer]= CARD[Outer]*(LEAST(ARL[Outer], SACL[Outer])+12)
(95)HSIZE[Inner] = CARD[Inner]*(LEAST(ARL[Inner], SACL[Inner])+12)
(96)MAXHASHAREA = CEIL(SMMAX*2/OPTBLKSIZE)
(97)HASHAREA = CEIL(LEAST(GREATEST(SAMAXIO*4/OPTBLKSIZE,SMMIN*2/OPTBLKSIZE),MAXHASHAERA*0.08))
(98)当HSIZE[Outer]>HASHAREA*OPTBLKSIZE,说明hash需要写入磁盘,否则IOCOST[Hash]=0
(99)BULDFRAGS = TRUNC(HSIZE[Outer]/OPTBLKSIZE+ 1)
(100)PROBEFRAGS = TRUNC(HSIZE[Inner]/OPTBLKSIZE+ 1)
(101)HASHBLKS = BULDFRAGS + PROBEFRAGS
(102)IOCOST[Hash] = CEIL(2*HASHBLKS/(MBRC-1)*(MREADTIM/SREADTIM+MBRC/TRUNC(SAMAXIO/OPTBLKSIZE) - (1+MREADTIM/SREADTIM/TRUNC(SAMAXIO/OPTBLKSIZE))))
(103)IOCOST[HJ]= IOCOST[Outer] + IOCOST[Inner] + IOCOST[Hash]

9.单表并行代价计算
当PPCT为默认值时
(104)IOCOST[Paralle1] = IOCOST[Serial]*10/9/DOP
当PPCT不为默认值时
(105)IOCOST[Paralle1]= GREATEST(0,1-PPCT)*IOCOST[Serial]+ PPCT*IOCOST[Serial]*10/9/DOP

10.两表关联并行代价计算
(106)SACL[Outer]= ACL[OuterColl]+...ACL[OuterColn]
(107)SACL[Inner]= ACL[InnerColl]+...ACL[InnerColn]
(108)HSIZE[Outer]= CARD[Outer]*(LEAST(ARL[Outer], SACL[Outer])+12)
(109)HSIZE[Inner]= CARD[Inner]*(LEAST(ARL[Outer], SACL[Inner])+12)
(110)#PTNS = GREATEST( DOP[Outer], DOP[Inner])
(111)MAXHASHAREA= GREATEST(160,SMINIO*4/OPTBLKSIZE,CEIL(SMPXMAX*2/#PTNS/OPTBLKSIZE),SMMAX/(160* 1024))
(112)HASHAREA= CEIL(GREATEST(SMINIO*4/OPTBLKSIZE,MAXHASHAERA*0.2))
(113)当HSIZE[Outer]>HASHAREA*OPTBLKSIZE*#PTNS,说明hash需要写入磁盘,否则IOCOST[Hash]=0
(114)IOCOST[Outer](Paralle1)= ROUND(IOCOST[Outer](Seria1)*10/9/DOP[Outer])
(115)IOCOST[Inner](Paralle1) = ROUND(IOCOST[Inner](Seria1)*10/9/DOP[Inner])
(116)IOCOST[Hash] = CEIL(2*HASHBLKS/(MBRC-1 )*(MREADTIM/SREADTIM+MBRC/TRUNC(SAMINIO/OPTBLKSIZE)-(1 + MREADTIM/SREADTIM/TRUNC(SAMINIO/OPTBLKSIZE))))
(117)IOCOST[HJ]= IOCOST[Outer](Parallel)+IOCOST[Inner](Parallel)+IOCOST[Hash]

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。