我想知道在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') ;
答案 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但我不确定。