测试6——观察Optimizer_index_cost_adj 对执行计划的影响

简介:     在基于cbo的优化器模式下面,oracle会把sql语句的各种执行计划的成本做比较,取其最小的作为其最优执行计划,同时,在决定是用index scan 还是full table scan 访问一个表的时候,oracle会把index scan的执行成本转化为fts的成本,然后再根据其成本大小来决定执行计划,这个index scan 和full table scan 的比值即为 optimizer_index_cost_adj,这个初始化参数代表一个百分比,取值范围在1到10000之间.该参数表示索引扫描和全表扫描成本的比较。

    在基于cbo的优化器模式下面,oracle会把sql语句的各种执行计划的成本做比较,取其最小的作为其最优执行计划,同时,在决定是用index scan 还是full table scan 访问一个表的时候oracle会把index scan的执行成本转化为fts的成本,然后再根据其成本大小来决定执行计划,这个index scan full table scan 的比值即为 optimizer_index_cost_adj,这个初始化参数代表一个百分比,取值范围在1到10000之间.该参数表示索引扫描和全表扫描成本的比较。缺省值100表示索引扫描成本等价转换与全表扫描成本。

下面的例子具体说明了该参数的不同取值对执行计划的影响(下面的例子不能做为性能调整的根据,只是作为该参数的一个研究型文档,实际在调整该参数的时候,还是参考应用的类型(oltp/olap),及v$system_event 中的db file sequential readdb file scattered read的具体数值。

建立测试表

SQL> create table t as select * from dba_objects;
SQL> create index t_idx on t(owner);
SQL> SHOW PARAMETER OPTIMIZER_INDEX_COST_ADJ
NAME                                 TYPE        VALUE
------------------------------------ ----------- -----
optimizer_index_cost_adj             integer    100
SQL> SHOW PARAMETER DB_FILE
NAME                                 TYPE        VALUE
------------------------------------ ----------- -----
db_file_multiblock_read_count       integer     128
SQL> set autotrace traceonly explain;

SQL> select * from t where owner='HR';
Execution Plan
----------------------------------------------------------
Plan hash value: 1579008347
--------------------------------------------------------------------------------


| Id  | Operation   | Name  | Rows  | Bytes | Cost (%CPU)| Time    |
--------------------------------------------------------------------------------


|   0 | SELECT STATEMENT   |   |  2500 |505K|92   (0)| 00:00:02 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T     |  2500 |505K|92   (0)| 00:00:02 |
|*  2 |   INDEX RANGE SCAN   | T_INX |  2500 |   | 8   (0)| 00:00:01 |

--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("OWNER"='HR')

Note
-----
   - dynamic sampling used for this statement (level=2)

专门走一次全表扫描,看下cost是多少:

SQL>   select /*+ FULL(T) */ * FROM T WHERE owner='HR';


SQL>   select /*+ FULL(T) */ * FROM T WHERE owner='HR';
Execution Plan
----------------------------------------------------------
Plan hash value: 1601196873
--------------------------------------------------------------------------
| Id  | Operation | Name | Rows  | Bytes | Cost (%CPU)| Time|
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  ||  2500 |   505K|  1591  (1)| 00:00:20 |
|*  1 |  TABLE ACCESS FULL| T|  2500 |   505K|  1591   (1)| 00:00:20 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("OWNER"='HR')
Note
-----
   - dynamic sampling used for this statement (level=2)

默认的optimizer_index_cost_adj =100全表扫描的成本是1591,索引范围扫描的成本92此时索引扫描的成本要比全表扫描的成本低,调整optimizer_index_cost_adj 参数,调整的基点: 全表扫描成本/索引扫描成本

SQL> SET AUTOTRACE OFF;

SQL> SELECT 1591/92*100 FROM DUAL;

1591/92*100
-----------
 1729.34783


接下来,是重点,我们取一个比这个基数略大的数值:1731

SQL> ALTER SESSION SET OPTIMIZER_INDEX_COST_ADJ=1731;
Session altered.

SQL> SHOW PARAMETER OPTIMIZER_INDEX_COST_ADJ

NAME     TYPE VALUE
------------------------------------ ----------- ------------------------------
optimizer_index_cost_adj     integer1731


SQL> set autotrace traceonly explain;
SQL> select * from t where owner='HR';


Execution Plan
----------------------------------------------------------
Plan hash value: 1601196873


--------------------------------------------------------------------------
| Id  | Operation  | Name | Rows  | Bytes | Cost (%CPU)| Time|
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  | |  2500 |   505K|  1591   (1)| 00:00:20 |
|*  1 |  TABLE ACCESS FULL| T |  2500 |   505K|  1591   (1)| 00:00:20 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("OWNER"='HR')

Note
-----
   - dynamic sampling used for this statement (level=2)

可以看到,此时奇怪的事情发生了,这个查询居然是走的全表扫描,而不是索引,这个参数到底是如何决定的呢?

原来: 在比较的时候,Oracle会把索引扫描的成本转换为全表扫描的成本,和全表扫描的COST进行比较.这个转换需要一个转换因子.就是optimizer_index_cost_adj:

optimizer_index_cost_adj * (Index Scan Cost) = 等价的 Full Scan Cost(比如刚才1731*92=159252 > 1591*100,所以选择了全表扫描,因为这个参数的权重让oracle决定走全表扫描的cost更低)

这个 等价的 Full Scan Cost 就是来和全表扫描成本进行比较的.

而这个转换因子的临界值实际上就是Full Scan Cost 和 Index Scan Cost的比值.

即:

optimizer_index_cost_adj = Full Scan Cost / Index Scan Cost(刚才1591/92 *100 =1731)


然后,我们把这个因子降低一点,看看是不是就会走索引呢?继续实验:

SQL> ALTER SESSION SET OPTIMIZER_INDEX_COST_ADJ=1725;
Session altered.


SQL> select * from t where owner='HR';
Execution Plan
----------------------------------------------------------
Plan hash value: 1579008347
-------------------------------------------------------------------------------------

| Id  | Operation    | Name  | Rows  | Bytes | Cost (%CPU)| Time|

--------------------------------------------------------------------------------

|   0 | SELECT STATEMENT    |   |  2500 | 505K|  1589   (1)| 00:00:20 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T     |  2500 |505K|  1589   (1)| 00:00:20 |
|*  2 |   INDEX RANGE SCAN    | T_INX |  2500 |   | 138   (0)| 00:00:02 |


--------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("OWNER"='HR')
Note
-----
   - dynamic sampling used for this statement (level=2)

果然,此时又走的索引,但是cost变成了1589(我们知道full table scan的成本是1591),所以选择了成本较少的,那么这个值是怎么来的呢?

是实际的cost*optimizer_index_cost_adj 得到的(1589/1725=0.9211=92/100)


综上,我们明白了这个参数可以理解为一个权重的值,这个值越高,index scan的权重越小,越倾向于使用full table scan。一般OLTP系统里,建议设置较小的值10-50,这样就会有更多的查询走索引扫描,参考http://www.dba-oracle.com/oracle_tips_cost_adj.htm

For some OLTP systems, re-setting this parameter to a smaller value (between 10- to 30) may result in huge performance gains

相关文章
|
SQL 监控 测试技术
测试5——观察增量检查点
四:log file switch,会触发一个增量检查点,不过它会更新datafile header SQL> select cpdrt dirty,cpods on_disk_scn,cpodt on_disk_time,cphbt from x$kccc...
879 0
|
3天前
|
监控 JavaScript 测试技术
postman接口测试工具详解
Postman是一个功能强大且易于使用的API测试工具。通过详细的介绍和实际示例,本文展示了Postman在API测试中的各种应用。无论是简单的请求发送,还是复杂的自动化测试和持续集成,Postman都提供了丰富的功能来满足用户的需求。希望本文能帮助您更好地理解和使用Postman,提高API测试的效率和质量。
27 11
|
1月前
|
JSON Java 测试技术
SpringCloud2023实战之接口服务测试工具SpringBootTest
SpringBootTest同时集成了JUnit Jupiter、AssertJ、Hamcrest测试辅助库,使得更容易编写但愿测试代码。
60 3
|
2月前
|
JSON 算法 数据可视化
测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)
这篇文章是关于如何通过算法接口返回的目标检测结果来计算性能指标的笔记。它涵盖了任务描述、指标分析(包括TP、FP、FN、TN、精准率和召回率),接口处理,数据集处理,以及如何使用实用工具进行文件操作和数据可视化。文章还提供了一些Python代码示例,用于处理图像文件、转换数据格式以及计算目标检测的性能指标。
74 0
测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)
|
3月前
|
移动开发 JSON Java
Jmeter实现WebSocket协议的接口测试方法
WebSocket协议是HTML5的一种新协议,实现了浏览器与服务器之间的全双工通信。通过简单的握手动作,双方可直接传输数据。其优势包括极小的头部开销和服务器推送功能。使用JMeter进行WebSocket接口和性能测试时,需安装特定插件并配置相关参数,如服务器地址、端口号等,还可通过CSV文件实现参数化,以满足不同测试需求。
262 7
Jmeter实现WebSocket协议的接口测试方法
|
3月前
|
JSON 移动开发 监控
快速上手|HTTP 接口功能自动化测试
HTTP接口功能测试对于确保Web应用和H5应用的数据正确性至关重要。这类测试主要针对后台HTTP接口,通过构造不同参数输入值并获取JSON格式的输出结果来进行验证。HTTP协议基于TCP连接,包括请求与响应模式。请求由请求行、消息报头和请求正文组成,响应则包含状态行、消息报头及响应正文。常用的请求方法有GET、POST等,而响应状态码如2xx代表成功。测试过程使用Python语言和pycurl模块调用接口,并通过断言机制比对实际与预期结果,确保功能正确性。
272 3
快速上手|HTTP 接口功能自动化测试
|
3月前
|
JavaScript 前端开发 测试技术
ChatGPT与接口测试
ChatGPT与接口测试,测试通过
56 5
|
2月前
|
JavaScript 前端开发 API
vue尚品汇商城项目-day02【9.Home组件拆分+10.postman测试接口】
vue尚品汇商城项目-day02【9.Home组件拆分+10.postman测试接口】
43 0
|
4月前
|
网络协议 测试技术 网络安全
Python进行Socket接口测试的实现
在现代软件开发中,网络通信是不可或缺的一部分。无论是传输数据、获取信息还是实现实时通讯,都离不开可靠的网络连接和有效的数据交换机制。而在网络编程的基础中,Socket(套接字)技术扮演了重要角色。 Socket 允许计算机上的程序通过网络进行通信,它是网络通信的基础。Python 提供了强大且易于使用的 socket 模块,使开发者能够轻松地创建客户端和服务器应用,实现数据传输和交互。 本文将深入探讨如何利用 Python 编程语言来进行 Socket 接口测试。我们将从基础概念开始介绍,逐步引导大家掌握创建、测试和优化 socket 接口的关键技能。希望本文可以给大家的工作带来一些帮助~
|
5月前
|
存储
Postman 接口测试配置 Pre-request Script
Postman 接口测试配置 Pre-request Script
233 5
Postman 接口测试配置 Pre-request Script
下一篇
DataWorks