Oracle执行计划(6)-cost成本-连接成本
转自 http://blog.csdn.net/zengmuansha/article/details/7488018
1 嵌套连接成本
外部表成本+内部表成本*外部表数据行
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10000 | 312K| 1338K (2)| 04:27:46 |
| 1 | NESTED LOOPS | | 10000 | 312K| 1338K (2)| 04:27:46 |
| 2 | TABLE ACCESS FULL| A1 | 49708 | 1359K| 140 (3)| 00:00:02 |
|* 3 | TABLE ACCESS FULL| A2 | 1 | 4 | 27 (4)| 00:00:01 |
---------------------------------------------------------------------------
像这个执行计划来看 NETSTED LOOPS 成本=1338K
=49708*27+140
=1342256 =1342K
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10000 | 312K| 1381K (2)| 04:36:16 |
| 1 | NESTED LOOPS | | 10000 | 312K| 1381K (2)| 04:36:16 |
| 2 | TABLE ACCESS FULL| A2 | 10000 | 40000 | 29 (4)| 00:00:01 |
|* 3 | TABLE ACCESS FULL| A1 | 1 | 28 | 138 (3)| 00:00:02 |
---------------------------------------------------------------------------
=138*10000+29
=1380029 &&1381K
2 HSAH_JOIN(散列连接)
01 最优散列连接成本=构建表获取数据的成本+探查表获取数据的成本+CPU成本
02 一遍散列成本
(探查遍数+1)*( 探查表获取数据块数/IO取值量)+( 构建表获取数据块数/IO取值量)
所谓一遍散列 就是构建表大于HASH_AREA_SIZE 不得不分成多个区,那样必须转储到硬盘上. 这个没有具体从执行计划获得数据,而是通过10053事件获得.
03 多边散列成本
(探查遍数+1)*( 探查表获取数据块数/IO取值量)+( 构建表获取数据块数/IO取值量)
3排序归并连接
1 最优排序成本 表成本+CPU成本
2 一遍排序
排序内存大小参数 SORT_AREA_SIZE
从V$TEMPSTAT和v$MYSTAT获得当前回话的排序信息
排序转存储大小是数据量的2倍 比如6M的数据量转到磁盘需要12M空间.因为还有个排序树,排序树每个节点3个指针,指针在32位系统需要12字节. 因此实际需要排序的内存空间量是数据量的4倍到6倍.(64位系统指针更大些)
表成本+1遍IO成本
10053事件计算
1遍IO成本=(blocks to sort+io cost per pass * merge passes)
=(待排序的块+1次转存储排序段IO成本*转存储次数)
无排序归并成本 两个独立表访问之和.
笛卡尔归并成本 第一个表成本+第一个表基数*第二个表成本
------------------------------无关点分割线-------------------------------------------------
索引排序 (表扫描+索引成本+列排序+ROWID排序)
普通表ROWID=6字节,群集索引ROWID=8字节,分区表全局分区索引ROWID=10字节,本地ROWID=6字节分区索引
Select sortcode from t1 order by sortcode;
Select * from ( select * from t1 order by sortcode) where rowum<=10;
第二个查询比第一个快,因为里面没有发生排序,判断当前值是否值最大值 保存10个.然后再对这10行数据排序.
同理 MAX() 只要不断检查是否是最大值,无需排序;
Select xx,xxx,coun(*) from t1 group by xx,xxx 也无需排序因为COUNT(*)
Sort_area_size 空间分配: 排序的时候10%用于数据缓冲,25%用于排序树.
散列连接 1把最小数据集散列到内存中并构建桶;2读取探查表一行在连接列上使用散列函数获得桶编号;3匹配内存桶里是否有行,无则抛弃,有进步精确检查.
构建表选择是 数据量最小的 是bytes*rows
bytes=user_tabl_colunms.avg_col_len OR user_tables.avg_row_len