执行计划中cost计算方法,执行计划cost
概念:
blevel:二元高度=索引高度-1
clustering_factor:集群因子,扫描index scan得出的要扫描的表中block数,clustering_factor<=table blocks
索引扫描的计算公式:
cost =blevel +
ceil(leaf_blocks *effective index selectivity) +ceil(clustering_factor * effective table selectivity)
一下测试是在rule based optimizer used条件下
SQL> select leaf_blocks,blevel,clustering_factor from dba_indexes where index_name='IDX_T';
LEAF_BLOCKS BLEVEL CLUSTERING_FACTOR
----------- ---------- -----------------
112 1 776SELECT b.num_rows, a.num_distinct, a.num_nulls, utl_raw.cast_to_number(high_value) AS high_value, utl_raw.cast_to_number(low_value) AS low_value
, b.num_rows - a.num_nulls AS "NUM_ROWS-NUM_NULLS", utl_raw.cast_to_number(high_value) - utl_raw.cast_to_number(low_value) AS "HIGH_VALUE-LOW_VALUE"
FROM dba_tab_col_statistics a, dba_tables b
WHERE a.owner = b.owner
AND a.table_name = b.table_name
AND a.owner = 'SCOTT'
AND a.table_name = upper('TEST')
AND a.column_name = 'OBJECT_ID'
NUM_ROWS
NUM_DISTINCT NUM_NULLSHIGH_VALUELOW_VALUENUM_ROWS-NUM_NULLSHIGH_VALUE-LOW_VALUE
50736 507351538202 5073553818
effective index selectivity=(limit-low_value)/(high_value-low_value)
SQL> select (1000-2)/(53820-2) selectivity from dual; SELECTIVITY ----------- 0.018543982
SQL> SELECT OWNER FROM TEST WHERE OBJECT_ID<1000;
已选择953行。
执行计划
----------------------------------------------------------
Plan hash value: 1810195980
---------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
---------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 941 | 10351 | 19 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST | 941 | 10351 | 19 |
|* 2 | INDEX RANGE SCAN | IDX_T | 941 | | 4 |
---------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OBJECT_ID"<1000)1.回表io=ceil(clustering_factor * effective table selectivity)=19-4=15
2.blevel +ceil(leaf_blocks *effective index selectivity)
理论上是 cost值越大,SQL的执行计划就不好.
但是还有一个前提,就是你的表的分析数据要正确。
cost 值的计算,是根据数据库表的统计信息来计算的。
例如 你有一个 一百万行的表 ABC。 在 A 列上面有一个索引。
你
SELECT SUM(B) FROM ABC WHERE A = 100
在数据库没有表/索引的 相关统计信息的情况下, 这个 cost 确实是估计出来的一个大概的值。偏差可能 与这个表中的 A=100 的数量有多少相关。
比如 100万条记录里面, A=100 的数据只有一条 / A=100 的数据只有 十万条。 执行的时间可是差很多的。
但是如果表/索引 没有被分析过, 数据库对于
SELECT SUM(B) FROM ABC WHERE A = 100
还是
SELECT SUM(B) FROM ABC WHERE A = 1000
查询的计划,是一样的。
但是如果你的 表/索引, 是已经分析过了的, 那么 cost 所反映出来的值, 可能更精确一些。
因为在分析的时候,就能知道 A=100 的数据只有一条 还是有 十万条。
数据库可以根据需要,选择最佳的查询方案来进行处理。
假如 那一百万条数据中, A=100 的数据只有一条 ,而 A=1000的数据,有 八十万条。
那么很可能
SELECT SUM(B) FROM ABC WHERE A = 100
使用索引的查询计划
而
SELECT SUM(B) FROM ABC WHERE A = 1000
使用全表扫描的查询计划。
Oracle给出的衡量执行计划的单位
一般Cost越低 证明执行计划越合理