As previously discussed, the CBO assumes the actual costs and overheads associated with all I/Os to be the same, regardless of the type of I/O, unless told otherwise via the optimizer_index_cost_adj parameter.
Another key assumption the CBO makes by default is that all I/Os will be physical I/Os (PIO) and so be relatively expensive to perform and “worthy” of being costed.
However, this of course is not always the case with many of the blocks being requested and accessed by Oracle already cached in the buffer cache. In specific scenarios, the CBO can take the likely caching characteristics of indexes into consideration and reduce the cost of an index related execution path accordingly. Note however this only applies for I/Os associated for index specific blocks in specific scenarios where the same index is repeatedly accessed.
For example, in the case of a nested loop join where the inner table is typically accessed via an index look-up, the same index may repeatedly access the table many times within the loop. Many of the blocks associated with this index are therefore quite likely to be cached as the index structure is being continually accessed. Same scenario for an index look-up process as a result of an IN list condition. For each element in the IN list, an index is often used to look-up the corresponding value in the table, thereby accessing the specific index again and again for each element in the IN list. As the index is continually being accessed, many of its associated blocks are likely to already be cached in memory.
The purpose of the optimizer_index_caching parameter is to tell the CBO what percentage of index related blocks are likely to already be cached in the buffer cache during these types of operations and so should not be considered in the overall costings associated with the index related execution path. The default is 0 which means by default Oracle doesn’t consider any index blocks to ever be cached and all I/Os associated with an index during an index access path need to treated as PIOs and costed accordingly. If however the optimizer_index_caching parameter is set to say 25, it means that the CBO will consider 25% of all I/Os associated directly with index blocks are likely to already be cached and will therefore reduce the overall cost of index block I/Os by 25%.
As discussed previously, the CBO I/O based costing formula is:
basic index range scan cost = index blevel + ceil(index selectivity x leaf blocks) + ceil(table selectivity x clustering factor)
The optimizer_index_caching parameter adjusts the formula in the following manner by reducing just the index accesses portion of the formula:
basic index range scan cost = ceil((index blevel + ceil(index selectivity x leaf blocks)) x (1- optimizer_index_caching)) + ceil(table selectivity x clustering factor)
but only for specific index scans such as nested loop joins and IN list conditions where an index is likely to be continually accessed within the same execution path.
So if we were to go back to the example I covered in the single predicate demo in the first CBO and Indexes Introduction post as shown below:
SQL> select * from bowie_stuff2 where id = 420;
2000 rows selected.
Execution Plan
———————————————————-
Plan hash value: 134336835
——————————————————————————
|Id| Operation | Name | Rows | Bytes | Cost |
——————————————————————————
|0| SELECT STATEMENT | | 2000 | 36000 | 18 |
|1| TABLE ACCESS BY INDEX ROWID| BOWIE_STUFF2 | 2000 | 36000 | 18 |
|*2| INDEX RANGE SCAN | BOWIE_STUFF2_I | 2000 | | 9 |
——————————————————————————
we notice that the cost of the execution plan is 18.
If we now change the optimizer_index_caching parameter to say 75, meaning that 75% of all index blocks are now likely to be cached and rerun the query:
SQL> alter system set optimizer_index_caching=75;
System altered.
SQL> select * from bowie_stuff2 where id = 420;
2000 rows selected.
Execution Plan
———————————————————-
Plan hash value: 134336835
——————————————————————————
|Id| Operation | Name | Rows | Bytes | Cost |
——————————————————————————
|0| SELECT STATEMENT | | 2000 | 36000 | 18 |
|1| TABLE ACCESS BY INDEX ROWID| BOWIE_STUFF2 | 2000 | 36000 | 18 |
|*2| INDEX RANGE SCAN | BOWIE_STUFF2_I | 2000 | | 9 |
——————————————————————————
we notice that the cost remains unchanged at 18 and parameter has had no effect, as the query was based on a single table equality predicate and did not have processing involving either a nest loop or IN list condition.
However, if we run the second IN list predicate demo involving an IN list condition as shown below (first resetting the optimizer_index_caching parameter back to 0):
SQL> alter system set optimizer_index_caching=0;
System altered.
SQL> SELECT * FROM bowie_stuff2 WHERE id in (20, 30, 420);
6000 rows selected.
Execution Plan
———————————————————-
Plan hash value: 2964430066
——————————————————————————-
|Id| Operation | Name | Rows | Bytes | Cost |
——————————————————————————-
|0| SELECT STATEMENT | | 6000 | 105K| 49 |
|1| INLIST ITERATOR | | | | |
|2| TABLE ACCESS BY INDEX ROWID| BOWIE_STUFF2 | 6000 | 105K| 49 |
|*3| INDEX RANGE SCAN | BOWIE_STUFF2_I | 6000 | | 23 |
——————————————————————————-
We note we had a cost of 49. Remember, the cost of 49 was calculated in the following manner as we have 3 elements in the IN list condition:
cost = index blevel + ceil(index selectivity x leaf blocks) + ceil(table selectivity x clustering factor)
= 2 + 3 x ceil(0.01 x 602) + ceil(0.03 x 852)
= 2 + 3×7 + 26
= 2 + 21 + 26
= 23 + 26 = 49
If we now alter the optimizer_index_caching parameter to 75 and rerun the same IN list query:
SQL> alter system set optimizer_index_caching=75;
System altered.
SQL> SELECT * FROM bowie_stuff2 WHERE id in (20, 30, 420);
6000 rows selected.
Execution Plan
———————————————————-
Plan hash value: 2964430066
——————————————————————————-
|Id| Operation | Name | Rows | Bytes | Cost |
——————————————————————————-
|0| SELECT STATEMENT | | 6000 | 105K| 32 |
|1| INLIST ITERATOR | | | | |
|2| TABLE ACCESS BY INDEX ROWID| BOWIE_STUFF2 | 6000 | 105K| 32 |
|*3| INDEX RANGE SCAN | BOWIE_STUFF2_I | 6000 | | 6 |
——————————————————————————-
we notice the cost has been reduced from 49 down to 32. How has the optimizer_index_caching set to 75 changed the costs:
basic index range scan cost = ceil((index blevel + ceil(index selectivity x leaf blocks)) x (1- optimizer_index_caching)) + ceil(table selectivity x clustering factor)
= ceil((2 + 3 x ceil(0.01 x 602)) x (1-0.75)) + ceil(0.03 x 852)
= ceil((2 + (3×7)) x 0.25) + 26
= ceil((2 + 21) x 0.25)+ 26
= 6 + 26 = 32
So whereas previously there were 23 index block I/Os, this has been reduced down to just 6. Note that the I/Os and associated costs with accessing the actual table blocks within the index scan remains unaltered.
So how to set this parameter in a database ? Well, there are a number of issues with it all.
Firstly, as with the optimizer_index_cost_adj parameter, there’s only the one “global” parameter (for the system or session) which means any value needs to be averaged out for all indexes and for all situations in which this parameter can have an effect. However, some indexes may for example be quite small and heavily accessed and as such quite likely to have most index blocks cached at any point in time (including leaf blocks) whereas other indexes may be quite huge and rarely and randomly accessed which means perhaps only the branch level blocks are likely to be cached even during a (say) IN list operation. As discussed previously, with all averages there will likely be examples where the value is appropriate, too high or too low depending the the characteristics of specific indexes.
Secondly, the poor table related blocks don’t have an equivalent parameter and so Oracle always assumes not only the table blocks within an index scan will be PIOs, but a FTS will only ever consist of PIOs, which conversely might not always be the case. So while we might make a reasonable guesstimate of the likelihood of an index block being cached (say via the buffer cache hit ratio, a study of the v$bh view, etc.), the CBO makes so such allowances for the possible caching characteristics of table related blocks. Yes, index blocks are more likely to be cached, especially during the specific scenarios in which the optimizer_index_caching parameter has an effect, but that doesn’t mean table blocks will always be PIOs. Therefore simply setting this parameter to what might appear a reasonable generalistic index caching value might still run the risk of favouring indexes unduly, even though it only impacts the index accessed blocks in the costing formula, as the CBO doesn’t make any such cost allowances for table blocks that might be cached in a FTS.
In the ideal world, we would have some idea of the caching characteristics of all individual indexes and tables and based on the segments being accessed and their associated caching characteristics, have the CBO make the necessary adjustments to it’s costing estimates in an execution path. Until we reach such an ideal world (which might not be that far away BTW), I basically recommend not to set this parameter at all and again simply ensure you use accurate system statistics and have accurate enough segment statistics.
I recommend setting this parameter if and when you find the CBO is commonly not choosing appropriate indexes for the above mentioned scenarios when perhaps it should and a slight “nudge” of costs in the right direction is sufficient to address the issues. The optimizer_index_caching parameter is not quite as overly “dangerous” if set incorrectly as the optimizer_index_cost_adj parameter can be, as it only impacts the “half” of the formula relating directly to index block I/Os and not the table block I/Os, which often constitute the greater proportion of overall I/Os in many index range scan operations (although as my example above shows, this depends as well).
However, with both of the optimizer_index parameters set, they can both have a hand in reducing the overall costs of an index related execution plan. The optimizer_index_caching parameter first impacts the cost of just the half of the formula relating to index block I/Os as shown above and then the optimizer_index_cost_adj parameter further impacts the overall resultant cost. So if we were to run the IN list query again, but this time also set the optimizer_index_cost_adj to say 25 as well as leaving the optimizer_index_caching to 75:
SQL> alter system set optimizer_index_cost_adj=25;
System altered.
SQL> SELECT * FROM bowie_stuff2 WHERE id in (20, 30, 420);
6000 rows selected.
Execution Plan
———————————————————-
Plan hash value: 2964430066
——————————————————————————-
|Id| Operation | Name | Rows | Bytes | Cost |
——————————————————————————-
|0| SELECT STATEMENT | | 6000 | 105K| 8 |
|1| INLIST ITERATOR | | | | |
|2| TABLE ACCESS BY INDEX ROWID| BOWIE_STUFF2 | 6000 | 105K| 8 |
|*3| INDEX RANGE SCAN | BOWIE_STUFF2_I | 6000 | | 2 |
——————————————————————————-
We note the the cost of the execution plan has further reduced down from 32 to just 8. Basically it’s just the previous cost of 32 x optimizer_index_cost_adj = 32 x 0.25 = 8.
However, rather than setting either of these parameters, I would simply recommend the appropriate use of system statistics and the CPU costing model as I’ll discuss later.
参考至:http://richardfoote.wordpress.com/2009/09/01/optimizer_index_caching-parameter/
如有错误,欢迎指正
邮箱:czmcj@163.com
相关推荐
赠送jar包:flink-optimizer_2.11-1.7.1.jar 赠送原API文档:flink-optimizer_2.11-1.7.1-javadoc.jar 赠送源代码:flink-optimizer_2.11-1.7.1-sources.jar 包含翻译后的API文档:flink-optimizer_2.11-1.7.1-...
赠送jar包:flink-optimizer_2.11-1.13.2.jar; 赠送原API文档:flink-optimizer_2.11-1.13.2-javadoc.jar; 赠送源代码:flink-optimizer_2.11-1.13.2-sources.jar; 赠送Maven依赖信息文件:flink-optimizer_2.11-...
赠送jar包:flink-optimizer_2.11-1.7.1.jar 赠送原API文档:flink-optimizer_2.11-1.7.1-javadoc.jar 赠送源代码:flink-optimizer_2.11-1.7.1-sources.jar 包含翻译后的API文档:flink-optimizer_2.11-1.7.1-...
Dell-Precision-Optimizer_82GT9_WIN_4.0.10_A00.exe (一下内容复制粘贴仅供参考) 文件格式: Update Package for Microsoft® Windows® 文件名: Dell-Precision-Optimizer_82GT9_WIN_4.0.10_A00.EXE 下载类型: ...
`mysql> select /*+ set_var(optimizer_switch='index_merge=off') set_var(join_buffer_size=4M) */ c_id from customer limit 1;` 这个新特性可以在查询语句中直接修改会话变量,不需要再进行多个步骤的操作。 ...
- `zend_optimizer_set_level(level)`:用于动态调整优化级别。 - `zend_optimizer_get_level()`:获取当前的优化级别。 这些函数使得开发者能够在运行时根据实际需求调整优化策略,从而达到最佳的性能平衡。 ####...
Image_Optimizer_v4带破解,很好用的图片压缩工具,占用空间小,压缩质量很好,速度也很快
"ZendOptimizer_linux" 是一个专为Linux操作系统设计的软件工具,它的主要功能是对使用Zend加密技术加密过的PHP文件进行解密。这里的"Zend"指的是Zend Technologies,一家知名的PHP开发公司,而"Optimizer"则暗示了...
赠送jar包:flink-optimizer_2.11-1.10.0.jar; 赠送原API文档:flink-optimizer_2.11-1.10.0-javadoc.jar; 赠送源代码:flink-optimizer_2.11-1.10.0-sources.jar; 赠送Maven依赖信息文件:flink-optimizer_2.11-...
matlab_Gray Wolf Optimizer_GWO_优化器_灰狼优化器 GWO算法模仿自然界中灰狼的领导层级和狩猎机制。采用 alpha、beta、delta 和 omega 四种类型的灰狼来模拟领导层级。此外,还实现了狩猎、寻找猎物、包围猎物和...
标题“IDM Optimizer_tools_”与描述“Internet Download Manager Optimizer”提示我们,这个压缩包可能包含了一款用于优化Internet Download Manager(IDM)的工具或软件。IDM是一款广受欢迎的下载管理器,它允许...
mysql查询优化,索引原理,各种查询优化教程。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。...
《WinXP_IIS_MySql_PHP_ZendOptimizer_phpMyAdmin环境配置安装指南》 本文将详细阐述如何在Windows XP SP2系统上配置一个完整的Web开发环境,包括IIS web服务器、MySQL数据库、PHP编程语言以及Zend Optimizer和...
提供的"Grey_Wolf_Optimizer_灰狼_灰狼算法_源码.zip"文件包含了灰狼优化器的源代码,通过对代码的阅读和理解,可以更深入地了解算法的细节,包括各个阶段的计算过程、参数设置以及如何适应具体问题。对于学习和实践...
标题 "New-folder.rar_Ant Lion_Ant lion optimizer_lion_lion algorithm" 提及的核心概念是“蚁狮优化器”(Ant Lion Optimizer, ALO),这是一款基于生物行为的优化算法,灵感来源于蚁狮捕食的行为。蚁狮优化器在...
赠送jar包:flink-optimizer_2.11-1.13.2.jar; 赠送原API文档:flink-optimizer_2.11-1.13.2-javadoc.jar; 赠送源代码:flink-optimizer_2.11-1.13.2-sources.jar; 赠送Maven依赖信息文件:flink-optimizer_2.11-...
Mu Online Game Server Optimizer. A very useful tools.
在本项目中,我们探讨了一种新颖的元启发式优化算法,它受到了海洋水母行为的启发,称为“matlab_Search_Optimizer_algorithm”。这种算法借鉴了水母在海洋环境中的生存策略,如群体协作、动态适应性以及对环境变化...
Particle swarm optimizer, in matlab