In the previous entry regarding The CBO and Indexes, we saw how the CBO with a query that selected 5 distinct values in an IN list, representing 5% of the data, decided to use a FTS because the costs of doing so were less than that of using a corresponding index. These costs (using the I/O costing model) represented the number of expected I/Os and the FTS was basically going to perform fewer I/Os than the index. Less I/Os, less cost and so the FTS was selected as the preferred access path.
However, by default, the CBO when determining these costs via the I/O costing model makes two very important assumptions which may not necessarily be true.
Assumption one is that all I/Os are likely to be “physical I/Os” which all need to be costed and taken into account.
Assumption two is that all I/Os are costed equally, even though the size of a multiblock I/O performed typically during a FTS is larger and so potentially more costly than a single block I/O usually associated with an index access.
Today, I’m only going to focus on this second assumption.
Now, when performing and processing data from a multiblock I/O as performed during a FTS operation, it’s typical for such operations to be more resource intensive than that of a single block I/O as performed during an index range scan, as the associated overheads are likely be greater such as having to read more actual data off the disk, having to transfer more data into the SGA, having to process more data in each associated block, etc.
Therefore, not all I/Os are equal. However, by default the CBO ignores all these possible differences and costs all I/Os associated with a FTS (multiblock) and an index (single block) as being equivalent or the same.
Now, this hardly seems fair or indeed accurate and desirable when determining the true cost differences between an index and a FTS. Shouldn’t the fact that a single block I/O is likely to be less resource intensive and take less elapsed time to process be taken into consideration when determining these relative costs ?
Enter the optimizer_index_cost_adj parameter.
The purpose of this parameter is simply to “adjust” the corresponding costs associated with an index to (hopefully) more accurately reflect the relative I/O costs between using an index and a FTS. If for example a single block I/O only takes 1/2 the time and resources to perform compared to a multiblock I/O, shouldn’t these associated I/O cost differences be reflected when determining whether or not to use an index and perhaps reduce the index related costs by 1/2 as a result ?
This parameter has a very simple impact on how the CBO costs the use of an index based access path. It takes the value of the optimizer_index_cost_adj as a percentage and adjusts the cost of an index related range scan access path to only be the corresponding percentage of the total index cost. By default, it has a value of 100 meaning that a single block I/O is 100% when compared to that of a multiblock I/O which in turn means that the index related I/O costs are treated the same as that of a multiblock FTS I/O. A default value of 100 therefore has no effect on the overall cost of using an index related access path.
However, if the optimizer_index_cost_adj only has a value of (say) 25, it means that all single block I/O are only 25% as costly as that of a multiblock I/O and so index related range scan costs are adjusted to be only 25% of that of the total index access path cost.
Going back to the previous demo where the FTS was selected, I calculated the cost of using the index when retrieving the 5% of data to be:
index blevel + ceil(index selectivity x leaf blocks) + ceil(table selectivity x clustering factor)
2 + 5 x ceil(0.01 x 602) + ceil(0.05 x 854) = 2 + 5 x 7 + 43 = 37 + 43 = 80.
The cost of using a FTS was calculated as being only 65. A cost of 65 for the FTS is less than a cost of 80 for the index and so the FTS was selected.
This time, the linked demo sets the optimizer_index_cost_adj = 25 before running the exact same query again.
We notice of couple of key differences. The first obvious difference is that the plan has changed and that the CBO has now decided to use the index. The second difference is the associated cost relating to the use of the index. Previously, it was calculated as being 80 but now it only has a cost of 20. The maths is pretty simple as with an optimizer_index_cost_adj = 25, we need only mutliply the previous total with 0.25:
(2 + 5 x ceil(0.01 x 602) + ceil(0.05 x 854)) x 0.25 = (2 + 5 x 7 + 43) x 0.25= 80 x 0.25 = 20.
Note also that just the index range scan cost component was previously 2 + 5 x ceil(0.01 x 602) = 37, but is now also adjusted to 37 x 0.25 which rounds to9.
Basically by setting the optimizer_index_cost_adj = 25, we have effectively reduced the overall cost of using the index based execution path down from 80 to just 20, to just 25% of the previous total index cost.
The cost of the FTS remains unchanged at 65. The index access path at just 20 is now less than the FTS alternative and so the index is now chosen by the CBO.
Yes, all these numbers and costs make sense when one understands how the CBO performs its calculations and the effect of setting the optimizer_index_cost_adj parameter to a non-default value.
The optimizer_index_cost_adj parameter can therefore obviously have a very significant impact in the behaviour and subsequent performance of the database as the CBO will reduce (or maybe increase) the actual costs of index related access paths by the percentage denoted in the optimizer_index_cost_adj parameter. It can potentially dramatically increase (or decrease) the likelihood of an index access path being chosen over a FTS.
There are typically 3 very different ways in which this parameter is set, which I’ll list in increasing order of preference.
1) Set it arbitrarily to a very low figure such that indexes reign supreme as their associated costs get adjusted to such a low figure by the CBO that a FTS access path has little chance of being chosen (for example, here’s a suggestion to set it to a magical value of 12). Generally a very bad thing to do in any database …
2) Set it to a value that the DBA determines is an approximate percentage of the costs associated with a single block I/O when compared to a multiblock I/O. An improvement of option 1), but I still prefer the next option 3) …
3) Leave it at the default value of 100 such that it has no impact and the CBO does not use it to adjust the cost of an index access path
I’ll explain in Part II a sensible approach in setting the optimizer_index_cost_adj parameter and why option 3 is the preferred option with any currently supported version of Oracle.
参考至:http://richardfoote.wordpress.com/2009/07/08/the-cbo-and-indexes-optimizer_index_cost_adj-part-i/
如有错误,欢迎指正
邮箱:czmcj@163.com
相关推荐
- `OPTIMIZER_INDEX_COST_ADJ`:此参数在Oracle 8i中引入,旨在帮助CBO更好地评估索引访问路径与全表扫描之间的成本。但在版本9i及以上版本中,由于CBO算法已经足够智能,通常无需手动调整该参数。 - `OPTIMIZER_...
【CBO原书代码】是关于Oracle数据库优化器(Cost-Based Optimizer,简称CBO)的学习资源,由知名Oracle专家Jonathan Lewis编著。CBO是Oracle数据库系统中用于选择执行SQL查询最佳执行路径的关键组件。它通过计算不同...
影响优化器优化目标的因素主要有三个:OPTIMIZER_MODE 初始化参数、数据字典中的 CBO 统计数据、用来改变 CBO 优化目标的 Hints。 OPTIMIZER_MODE 初始化参数 ------------------------- OPTIMIZER_MODE 初始化...
Oracle 优化器有两种优化方式:基于规则的优化方式(Rule-Based Optimization,简称为 RBO)和基于代价的优化方式(Cost-Based Optimization,简称为 CBO)。 基于规则的优化方式(RBO)是指优化器在分析 SQL 语句...
CBO(Cost-Based Optimizer)和 RBO(Rule-Based Optimizer)是两种不同的优化器模式。CBO 根据成本估算选择执行计划,而 RBO 遵循简单的分级方法,使用 15 种级别要点,当接收到查询时,优化器将评估使用到的要点...
2. SQL优化:9i和10g都支持绑定变量、索引优化、物化视图、并行查询等,10g更是强化了统计信息的收集和CBO的智能化。 3. 数据库链接:跨数据库操作在9i和10g中得到支持,允许在不同数据库间传递数据和调用远程过程...
1. CBO:CBO尝试找到最低成本的访问数据的方法,以提高数据库的性能。它使用统计信息来确定执行计划。 2. RBO:RBO遵循简单的分级方法学,使用15种级别要点来评估查询时的成本。 三、资源消耗的SQL查询 如何定位...
- Oracle提供CBO(Cost-Based Optimizer)和RBO(Rule-Based Optimizer)两种优化器。 - 通过`OPTIMIZER_MODE`或`OPTIMIZER_GOAL`参数设置优化器模式,如`ALTER SESSION SET OPTIMIZER_GOAL=FIRST_ROWS`。 - 使用...
Oracle的Cost-Based Optimizer (CBO) 是一种自动选择最优执行计划的机制,它通过评估不同执行路径的成本来决定如何执行SQL查询。CBO会考虑各种因素,包括表的大小、索引的存在、数据分布等,以确定最有效率的查询...
* CBO(Cost-Based Optimization):基于成本的优化方式,Oracle 会根据表和索引的统计信息来计算运行 SQL 语句采用不同的执行计划所要耗费的成本。 * RULE(Rule-Based Optimization):基于规则的优化方式,Oracle...
在Oracle数据库管理中,CBO(Cost-Based Optimizer)是一种重要的查询优化策略,它根据操作的成本来决定最佳的执行计划。CBO通过分析表的统计信息,如行数、块数、索引信息等,来评估不同执行路径的代价,并选择最低...
3. 使用 Cost-Based Optimizer (CBO):设置optimizer_mode参数,CBO 需要统计信息,RBO 会选择不合适的索引 4. 定位资源消耗高的 SQL:根据 v$sqlarea 中的逻辑读/disk_read 和 CPU 使用率,查找当前 session 的当前...
通过合理配置OPTIMIZER_MODE参数、维护准确的CBO统计数据、灵活运用Hints,可以显著提升数据库系统的查询性能,满足不同应用场景的需求。在实践中,应根据应用特性选择最合适的优化目标,并结合统计信息的更新维护,...
- SQL优化改进,如CBO(Cost-Based Optimizer)的增强。 - Flashback Technology,支持快速回滚到数据库的某个历史状态。 3. **Unicode支持** OCI在11g版本中支持Unicode,这意味着开发者可以处理多种语言的数据...
本文旨在深入探讨成本基础优化器(Cost-Based Optimizer,简称CBO)在Oracle数据库中的工作方式及其重要性。通过一个具体的示例,我们将逐步分析CBO如何根据表统计信息来选择最优查询执行计划。 #### CBO的基本概念...
CBO(Cost-Based Optimizer)是一种基于成本的优化器,RBO(Rule-Based Optimizer)是一种基于规则的优化器。CBO需要使用统计信息,据此计算最佳的执行计划,而RBO根据Oracle设定好的规则生成执行计划。由于不能窥视...