Oracle 11g r2:索引上的奇怪行为

时间:2014-11-28 15:35:28

标签: oracle11g indexing

我有查询:

    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;

如果我使用AND LOG.DATA_PROC> = TRUNC(SYSDATE)-3执行查询,Oracle会使用MS042_LOADING_LOGS(LOG)表的data_proc字段上的索引,如果我使用,则使用AND LOG.DATA_PROC> = TRUNC(SYSDATE)-4或-5,或-6等,它使用表访问完整。为什么会这样? 我还执行了一个:

ALTER INDEX MS042_DATA_PROC_IDX REBUILD;

但没有变化。
谢谢,
伊戈尔


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

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)

1 个答案:

答案 0 :(得分:1)

将返回的行的分数越大,表扫描的效率越高,使用索引的效率越低。显然,Oracle期望在查询返回超过3天的数据时出现拐点。如果这不准确,我希望你的表或索引的统计数据不准确。