Oracle索引时间戳

时间:2018-04-26 10:48:59

标签: sql oracle oracle11g query-performance

情境:

我有一个包含568801行的表和列TIM_RECEPT(TIMESTAMP)上的索引。索引生成为TRUNC("TIM_RECEPT")

此表格于4月19日填写此查询:

INSERT INTO MY_TABLE SELECT <fields> FROM <tables>

接下来的几天表格已加载:

INSERT INTO MY_TABLE SELECT <fields> 
FROM <tables> WHERE alias.tim_recept > TRUNC(SYSDATE -1)

问题:

当我在解释计划中使用索引时,请返回:

EXPLAIN PLAN FOR
select *
from  MY_TABLE
where trunc(TIM_RECEPT) >= TO_DATE('22/11/2017', 'DD-MM-YYYY')
    and trunc(TIM_RECEPT) <= TO_DATE('26/04/2018', 'DD-MM-YYYY')
;

select * from table(dbms_xplan.display);

-----------------------------------------------------------------------------------------
| Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |           | 42112 |    13M|  8690   (1)| 00:01:45 |
|   1 |  TABLE ACCESS BY INDEX ROWID| MY_TABLE  | 42112 |    13M|  8690   (1)| 00:01:45 |
|*  2 |   INDEX RANGE SCAN          | IMYTABLE1 | 42112 |       |   114   (0)| 00:00:02 |
-----------------------------------------------------------------------------------------

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

   2 - access(TRUNC(INTERNAL_FUNCTION("TIM_RECEPT"))>=TO_DATE(' 2017-11-22 
              00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND 
              TRUNC(INTERNAL_FUNCTION("TIM_RECEPT"))<=TO_DATE(' 2018-04-26 00:00:00', 
              'syyyy-mm-dd hh24:mi:ss'))

但是如果我更改初始日期并休息一天,则不使用索引:

EXPLAIN PLAN FOR
select *
from  MY_TABLE
where trunc(TIM_RECEPT) >= TO_DATE('21/11/2017', 'DD-MM-YYYY')
    and trunc(TIM_RECEPT) <= TO_DATE('26/04/2018', 'DD-MM-YYYY')
;

select * from table(dbms_xplan.display);

------------------------------------------------------------------------------
| Id  | Operation         | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |          | 42395 |    14M|  8739   (1)| 00:01:45 |
|*  1 |  TABLE ACCESS FULL| MY_TABLE | 42395 |    14M|  8739   (1)| 00:01:45 |
------------------------------------------------------------------------------

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

   1 - filter(TRUNC(INTERNAL_FUNCTION("TIM_RECEPT"))>=TO_DATE(' 
              2017-11-21 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND 
              TRUNC(INTERNAL_FUNCTION("TIM_RECEPT"))<=TO_DATE(' 2018-04-26 00:00:00', 
              'syyyy-mm-dd hh24:mi:ss'))

关于这个问题的任何想法?

1 个答案:

答案 0 :(得分:2)

Oracle优化器不使用索引i snot必要的问题。这是一个问题 当FULL TABLE SCAN访问所消耗的资源(在大多数情况下已用时间)高于a { 使用INDEX ACCESS的替代执行计划(您不是明确状态)。

从优化器的角度出发,两个执行计划都很好并且导致大致相同的时间。

因此,如果这些查询的经验不同,实际经过的时间与估计(01:45)有很大不同 您(或您的DBA))应采取以下步骤:

1)验证表的优化程序统计信息

过时的统计信息可能会欺骗优化器。特别是如果你收集小桌子上的统计数据和 插入大量记录。

2)验证优化程序参数和系统统计信息

某些参数DB_FILE_MULTIBLOCK_READ_COUNTFTSINDEX ACCES之间的选择密切相关。

类似对System Statistics设置有效。

最后备注

要访问大表的非平凡部分(例如100天内50个),不一定是INDEX ACCESS的用例。检查分区功能,(range partitioning) 是为这种访问而设计的。