Buenas,
Cita: En la aplicación el usuario tiene que introducir obligatoriamente un rango de fechas (FECHADESDE, FECHAHASTA) que luego se añade a la cáusula WHERE de todas las consultas de esta manera: FECHADESDE >= :fecDesde AND FECHASTA <= :fecHasta, con lo cual en principio los índices no valdrían para nada puesto que no estoy introduciendo una serie de valores concretos. La idea de añadirlo al índice consistiría en añadir a las consultas la cláusula AND TO_CHAR(TABLA.FECHADESDE, 'YYYY') = :año, teniendo en cuenta que casi todos los registros tienen FECHADESDE = FECHAHASTA y que casi todas las consultas suelen darse para rangos de fechas de un mismo año.
Me has hecho dudar y he realizado unas pruebas.
No tengo grandes conocimientos de como funciona el planificador de Oracle, pero me gusta la algoritmia y me defiendo con el planificador de postgres.
Asi que te enseño unas pruebas en postgres donde se ve que aunque sea un rango de fechas el indice mejora NOTABLEMENTE el rendimiento de la consulta. Por otra parte, cosa que me parecia muy lógico, pero me has hecho dudar.
Código:
create table fecha (id serial primary key, f_desde date, f_hasta date);
insert into fecha (f_desde, f_hasta) select '01/01/2000'::date +a, '01/01/2000'::date + a*2 from generate_series(1,10000) a;
Bueno una tabla con 2 fechas y 10000 registros.
La select trae 365 registros.
select *
from fecha
where f_desde >= TO_DATE('01/01/2001', 'dd/mm/yyyy')
and f_hasta <= TO_DATE('31/12/2003', 'dd/mm/yyyy')
El planificador me da:
Código:
"Seq Scan on fecha (cost=0.00..205.00 rows=645 width=12) (actual time=0.190..6.395 rows=365 loops=1)"
" Filter: ((f_desde >= '2001-01-01'::date) AND (f_hasta <= '2003-12-31'::date))"
"Total runtime: 6.545 ms"
Indexo las fechas
Código:
create index indice_fecha_d ON fecha(f_desde);
create index indice_fecha_h ON fecha(f_hasta);
El planificador me da:
Código:
"Index Scan using indice_fecha_h on fecha (cost=0.00..17.69 rows=645 width=12) (actual time=0.409..0.971 rows=365 loops=1)"
" Index Cond: (f_hasta <= '2003-12-31'::date)"
" Filter: (f_desde >= '2001-01-01'::date)"
"Total runtime: 1.132 ms"
El coste baja de 0..205 a 0..17
Cambia el recorrido secuencial por un Index Scan. Es decir, utiliza los indices!!!
El tiempo como ves tambien se reduce drasticamente.
Sigo sin saber porque descartas una opción que te llevaría 10 minutos probarla.
Espero que te sirva y nos cuentes.
Salu2