Oracle隐性转换导致访问索引的逻辑读增加

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执行频率高,这部分增加的逻辑读还是很可观的。

原文地址:https://www.cnblogs.com/PiscesCanon/p/13930059.html