Oracle隐性转换导致访问索引的逻辑读增加
前言
最近生产遇到隐性转换仍旧可以使用索引的问题,具体探究可以查看Oracle索引字段发生隐式转换仍然能够使用索引。
其中,也有另外一个问题,那就是在发生索引字段的隐性转换的情况下,索引访问的逻辑读增多。
具体描述
不发生隐性转换的:
Plan hash value: 731690389 ------------------------------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem | ------------------------------------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 0 |00:00:00.01 | 3 | | | | | 1 | HASH GROUP BY | | 1 | 1 | 0 |00:00:00.01 | 3 | 900K| 900K| | |* 2 | HASH JOIN | | 1 | 1 | 0 |00:00:00.01 | 3 | 1027K| 1027K| 227K (0)| |* 3 | TABLE ACCESS BY INDEX ROWID| USER_CONVERTX | 1 | 1 | 0 |00:00:00.01 | 3 | | | | |* 4 | INDEX RANGE SCAN | IDX_USER_CONVERTX_04 | 1 | 279K| 0 |00:00:00.01 | 3 | | | | |* 5 | TABLE ACCESS FULL | ABCDEF_GHIJ_KLMNOPQR | 0 | 30454 | 0 |00:00:00.01 | 0 | | | | ------------------------------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- ...省略部分内容... 4 - access("IS_XXXXXXX_XXXXXX"='0' AND "XXXXXXX_STATUS"='10' AND "STATUS"='31')
逻辑读为3。
发生隐性转换的:
Plan hash value: 3405430609 ------------------------------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem | ------------------------------------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 0 |00:00:00.53 | 6360 | | | | | 1 | HASH GROUP BY | | 1 | 1 | 0 |00:00:00.53 | 6360 | 900K| 900K| | |* 2 | HASH JOIN | | 1 | 1 | 0 |00:00:00.53 | 6360 | 1027K| 1027K| 191K (0)| |* 3 | TABLE ACCESS BY INDEX ROWID| USER_CONVERTX | 1 | 1 | 0 |00:00:00.53 | 6360 | | | | |* 4 | INDEX FULL SCAN | IDX_USER_CONVERTX_04 | 1 | 23966 | 0 |00:00:00.53 | 6360 | | | | |* 5 | TABLE ACCESS FULL | ABCDEF_GHIJ_KLMNOPQR | 0 | 30454 | 0 |00:00:00.01 | 0 | | | | ------------------------------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- ...省略部分内容... 4 - filter((TO_NUMBER("XXXXXXX_STATUS")=10 AND TO_NUMBER("STATUS")=31 AND TO_NUMBER("IS_XXXXXXX_XXXXXX")=0))
可以发现,逻辑读增加了6000多。
根据Oracle索引字段发生隐式转换仍然能够使用索引的探究,最后知道索引全扫描和索引快速全扫描是不受隐式转换影响的。
对比两者id4处,可以发现隐式转换的扫描了整个索引(INDEX FULL SCAN ),相比未发生隐式转换的(INDEX RANGE SCAN)当然是多了。
查看了该索引大小大约为52M,和6360*8/1024=50M接近。
因此,就算隐式转换可以使用索引,但是限制了访问该索引一定是索引全扫描和索引快速全扫描,这就可能导致逻辑读增加。
万一索引比较大并且SQL执行频率高,这部分增加的逻辑读还是很可观的。