甲骨文。在DATE列上创建索引

时间:2017-11-10 10:12:58

标签: oracle oracle12c

我想知道在CREATION_DATE字段中创建索引是否会对此查询进行任何改进

   select TO_CHAR(CREATION_DATE, 'HH24') || ':mm' HOUR, count ('1')  MESSAGE_HOUR
        from t_hotel             
           where TO_CHAR(CREATION_DATE, 'dd/mm/yyyy') = TO_CHAR(SYSDATE, 'dd/mm/yyyy') 
group by TO_CHAR(CREATION_DATE, 'HH24') 
    order by TO_CHAR(CREATION_DATE, 'HH24') ;

2 个答案:

答案 0 :(得分:2)

是的,您可以在CREATION_DATE列上利用基于函数的索引。

以下面的演示为例,我有一个列为date类型的表格。

create table t_hotel  (creation_date date);
insert into t_hotel select sysdate+0.5 from dual connect by level <=100;
100 rows affected
insert into t_hotel select sysdate+0.2 from dual connect by level <=100;
100 rows affected
 explain plan for  select TO_CHAR(CREATION_DATE, 'HH24') || ':mm' HOUR, count ('1')  MESSAGE_HOUR
        from t_hotel             
           where trunc(creation_date)= trunc(sysdate) 
group by TO_CHAR(CREATION_DATE, 'HH24') 
    order by TO_CHAR(CREATION_DATE, 'HH24') ;
select * from table(dbms_xplan.display());
| PLAN_TABLE_OUTPUT                                                              |
| :----------------------------------------------------------------------------- |
| Plan hash value: 353888308                                                     |
|                                                                                |
| ------------------------------------------------------------------------------ |
| | Id  | Operation          | Name    | Rows  | Bytes | Cost (%CPU)| Time     | |
| ------------------------------------------------------------------------------ |
| |   0 | SELECT STATEMENT   |         |   200 |  1800 |     4  (25)| 00:00:01 | |
| |   1 |  SORT GROUP BY     |         |   200 |  1800 |     4  (25)| 00:00:01 | |
| |*  2 |   TABLE ACCESS FULL| T_HOTEL |   200 |  1800 |     3   (0)| 00:00:01 | |
| ------------------------------------------------------------------------------ |
|                                                                                |
| Predicate Information (identified by operation id):                            |
| ---------------------------------------------------                            |
|                                                                                |
|    2 - filter(TRUNC(INTERNAL_FUNCTION("CREATION_DATE"))=TRUNC(SYSDATE@!)       |
|               )                                                                |
|                                                                                |
| Note                                                                           |
| -----                                                                          |
|    - dynamic sampling used for this statement (level=2)                        |
create index idx_cd on t_hotel(trunc(creation_date));
 explain plan for  select TO_CHAR(CREATION_DATE, 'HH24') || ':mm' HOUR, count ('1')  MESSAGE_HOUR
        from t_hotel             
           where trunc(creation_date)= trunc(sysdate) 
group by TO_CHAR(CREATION_DATE, 'HH24') 
    order by TO_CHAR(CREATION_DATE, 'HH24') ;
select * from table(dbms_xplan.display());
| PLAN_TABLE_OUTPUT                                                                        |
| :--------------------------------------------------------------------------------------- |
| Plan hash value: 2841908389                                                              |
|                                                                                          |
| ---------------------------------------------------------------------------------------- |
| | Id  | Operation                    | Name    | Rows  | Bytes | Cost (%CPU)| Time     | |
| ---------------------------------------------------------------------------------------- |
| |   0 | SELECT STATEMENT             |         |     2 |    36 |     3  (34)| 00:00:01 | |
| |   1 |  SORT GROUP BY               |         |     2 |    36 |     3  (34)| 00:00:01 | |
| |   2 |   TABLE ACCESS BY INDEX ROWID| T_HOTEL |     2 |    36 |     2   (0)| 00:00:01 | |
| |*  3 |    INDEX RANGE SCAN          | IDX_CD  |     1 |       |     1   (0)| 00:00:01 | |
| ---------------------------------------------------------------------------------------- |
|                                                                                          |
| Predicate Information (identified by operation id):                                      |
| ---------------------------------------------------                                      |
|                                                                                          |
|    3 - access(TRUNC(INTERNAL_FUNCTION("CREATION_DATE"))=TRUNC(SYSDATE@!))                |
|                                                                                          |
| Note                                                                                     |
| -----                                                                                    |
|    - dynamic sampling used for this statement (level=2)                                  |

dbfiddle here

答案 1 :(得分:0)

1)where子句应以不同方式书写。  where creation_date >= trunc(sysdate) and creation_date < trunc(sysdate+1)
2)您可以创建两个索引     - 正常create index idx_creation_date on t_hotel(creation_date);改进where子句。
    - fucntion base index create index idx_creation_date_hh24 on t_hotel(TO_CHAR(CREATION_DATE, 'HH24') );可能它会改进group by和orderby但我不确定。