简体   繁体   English

Oracle 11g r2:索引上的异常行为

[英]Oracle 11g r2: strange behavior on index

I have the query: 我有查询:

    SELECT count(*)
FROM 
(
SELECT
 TBELENCO.DATA_PROC, TBELENCO.POD, TBELENCO.DESCRIZIONE, TBELENCO.ERROR, TBELENCO.STATO,
 TBELENCO.SEZIONE, TBELENCO.NOME_FILE, TBELENCO.ID_CARICAMENTO, TBELENCO.ESITO_OPERAZIONE,
 TBELENCO.DES_TIPO_MISURA,
 --TBELENCO.RAGIONE_SOCIALE,
 --ROW_NUMBER() OVER (ORDER BY TBELENCO.DATA_PROC DESC) R
 ROWNUM R
FROM(
 SELECT
  LOG.DATA_PROC, LOG.POD, LOG.DESCRIZIONE, LOG.ERROR, LOG.STATO,
  LOG.SEZIONE, LOG.NOME_FILE, LOG.ID_CARICAMENTO, LOG.ESITO_OPERAZIONE, TM.DES_TIPO_MISURA
  --,C.RAGIONE_SOCIALE
  --ROW_NUMBER() OVER (ORDER BY LOG.DATA_PROC DESC) R 
 FROM
  MS042_LOADING_LOGS LOG JOIN MS116_MEASURE_TYPES TM ON
   TM.ID_TIPO_MISURA=LOG.SEZIONE
--  LEFT JOIN(
--   SELECT CUST.RAGIONE_SOCIALE,STR.POD,RSC.DATA_DA, RSC.DATA_A
--   FROM
--    MS038_METERS STR JOIN MS036_REL_SITES_CUSTOMERS RSC ON
--     STR.ID_SITO=RSC.ID_SITO
--    JOIN MS030_CUSTOMERS CUST ON
--     CUST.ID_CLIENTE=RSC.ID_CLIENTE    
--  ) C ON
--  C.POD=LOG.POD
  --AND LOG.DATA_PROC BETWEEN C.DATA_DA AND C.DATA_A   
  WHERE
   1=1 
   --AND LOG.DATA_PROC>=TRUNC(SYSDATE)
   AND LOG.DATA_PROC>=TRUNC(SYSDATE)-3
   --TO_DATE('01/11/2014', 'DD/MM/YYYY')
) TBELENCO
)
WHERE
 R BETWEEN 1 AND 200;

If I execute the query with AND LOG.DATA_PROC>=TRUNC(SYSDATE)-3, Oracle uses the index on the data_proc field of the MS042_LOADING_LOGS (LOG) table, if I use, instead, AND LOG.DATA_PROC>=TRUNC(SYSDATE)-4 or -5, or -6, etc, it uses a table access full. 如果我使用AND LOG.DATA_PROC> = TRUNC(SYSDATE)-3执行查询,那么,如果使用Oracle,则Oracle使用MS042_LOADING_LOGS(LOG)表的data_proc字段上的索引,而使用AND LOG.DATA_PROC> = TRUNC(SYSDATE) )-4或-5或-6等,它使用完整的表访问。 Why this behavior? 为什么会这样呢? I also execute a : 我也执行:

ALTER INDEX MS042_DATA_PROC_IDX REBUILD;

but with no changes. 但没有任何变化。
Thank, 谢谢,
Igor 伊戈尔


--*********************************************************** - ********* ***********

SELECT count(*)
FROM 
(
SELECT
 TBELENCO.DATA_PROC, TBELENCO.POD, TBELENCO.DESCRIZIONE, TBELENCO.ERROR, TBELENCO.STATO,
 TBELENCO.SEZIONE, TBELENCO.NOME_FILE, TBELENCO.ID_CARICAMENTO, TBELENCO.ESITO_OPERAZIONE,
 TBELENCO.DES_TIPO_MISURA,
 ROWNUM R
FROM(
 SELECT
  LOG.DATA_PROC, LOG.POD, LOG.DESCRIZIONE, LOG.ERROR, LOG.STATO,
  LOG.SEZIONE, LOG.NOME_FILE, LOG.ID_CARICAMENTO, LOG.ESITO_OPERAZIONE, TM.DES_TIPO_MISURA
 FROM
  MS042_LOADING_LOGS LOG JOIN MS116_MEASURE_TYPES TM ON
   TM.ID_TIPO_MISURA=LOG.SEZIONE
  WHERE
   1=1 
   AND LOG.DATA_PROC>=TRUNC(SYSDATE)-1
) TBELENCO
)
WHERE
 R BETWEEN 1 AND 200;

Plan hash value: 2191058229

-------------------------------------------------------------------------------------------------------
| Id  | Operation                       | Name                | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                |                     |     1 |    13 | 30866   (2)| 00:06:11 |
|   1 |  SORT AGGREGATE                 |                     |     1 |    13 |            |          |
|*  2 |   VIEW                          |                     | 94236 |  1196K| 30866   (2)| 00:06:11 |
|   3 |    COUNT                        |                     |       |       |            |          |
|*  4 |     HASH JOIN                   |                     | 94236 |  1104K| 30866   (2)| 00:06:11 |
|   5 |      INDEX FULL SCAN            | P087_TIPI_MISURE_PK |    15 |    30 |     1   (0)| 00:00:01 |
|   6 |      TABLE ACCESS BY INDEX ROWID| MS042_LOADING_LOGS  | 94236 |   920K| 30864   (2)| 00:06:11 |
|*  7 |       INDEX RANGE SCAN          | MS042_DATA_PROC_IDX | 94236 |       | 25742   (2)| 00:05:09 |
-------------------------------------------------------------------------------------------------------

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

   2 - filter("R"<=200 AND "R">=1)
   4 - access("TM"."ID_TIPO_MISURA"="LOG"."SEZIONE")
   7 - access(SYS_OP_DESCEND("DATA_PROC")<=SYS_OP_DESCEND(TRUNC(SYSDATE@!)-1))
       filter(SYS_OP_UNDESCEND(SYS_OP_DESCEND("DATA_PROC"))>=TRUNC(SYSDATE@!)-1)

Plan hash value: 69930686

---------------------------------------------------------------------------------------------
| Id  | Operation             | Name                | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |                     |     1 |    13 | 95921   (1)| 00:19:12 |
|   1 |  SORT AGGREGATE       |                     |     1 |    13 |            |          |
|*  2 |   VIEW                |                     |  1467K|    18M| 95921   (1)| 00:19:12 |
|   3 |    COUNT              |                     |       |       |            |          |
|*  4 |     HASH JOIN         |                     |  1467K|    16M| 95921   (1)| 00:19:12 |
|   5 |      INDEX FULL SCAN  | P087_TIPI_MISURE_PK |    15 |    30 |     1   (0)| 00:00:01 |
|*  6 |      TABLE ACCESS FULL| MS042_LOADING_LOGS  |  1467K|    13M| 95912   (1)| 00:19:11 |
---------------------------------------------------------------------------------------------

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

   2 - filter("R"<=200 AND "R">=1)
   4 - access("TM"."ID_TIPO_MISURA"="LOG"."SEZIONE")
   6 - filter("LOG"."DATA_PROC">=TRUNC(SYSDATE@!)-4)

The larger the fraction of rows that will be returned, the more efficient a table scan is and the less efficient it is to use an index. 将返回的行分数越大,表扫描越有效,并且使用索引的效率越低。 Apparently, Oracle expects that inflection point to come when the query returns more than 3 days of data. 显然,Oracle希望在查询返回超过3天的数据时出现拐点。 If that is inaccurate, I would expect that the statistics on your table or indexes are inaccurate. 如果这不准确,我希望您表或索引上的统计信息不准确。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM