Cada opción que involucra la manipulación CAST o TRUNCATE o DATEPART en el campo de fecha y hora tiene el mismo problema: la consulta debe escanear todo el conjunto de resultados (los 40k) para encontrar las fechas distintas. El rendimiento puede variar marginalmente entre varias implementaciones.
Lo que realmente necesita es tener un índice que pueda producir la respuesta en un abrir y cerrar de ojos. Puede tener una columna calculada persistente e indexar (requiere cambios en la estructura de la tabla) o una vista indizada (requires Enterprise Edition for QO to consider the index out-of-the-box).
persistentes de columna calculada:
alter table foo add date_only as convert(char(8), [datetimecolumn], 112) persisted;
create index idx_foo_date_only on foo(date_only);
vista indizada:
create view v_foo_with_date_only
with schemabinding as
select id
, convert(char(8), [datetimecolumn], 112) as date_only
from dbo.foo;
create unique clustered index idx_v_foo on v_foo_with_date_only(date_only, id);
actualización
para eliminar por completo la exploración podría utilizar un GROUP BY engañado vista indizada, como este:
create view v_foo_with_date_only
with schemabinding as
select
convert(char(8), [d], 112) as date_only
, count_big(*) as [dummy]
from dbo.foo
group by convert(char(8), [d], 112)
create unique clustered index idx_v_foo on v_foo_with_date_only(date_only)
En su lugar, la consulta select distinct date_only from foo
utilizará esta vista indizada. Sigue siendo un escaneo técnico, pero en un índice ya 'distinto', por lo que solo se escanean los registros necesarios. Es un truco, creo, no lo recomendaría para el código de producción en vivo.
AFAIK SQL Server no tiene la capacidad de escanear un índice verdadero con omisión de repeticiones, es decir. busca la cima, luego busca más que la cima, luego busca sucesivamente más que el último encontrado.
¿Hay alguna forma de utilizar 'SKIP SCAN' en' SQL Server'? Acabo de probar tu solución en una tabla '2M' y empeoró (' DISTINCT CAST (...) 'en un campo' DATETIME' tomó '850 ms' con' Hash Match Aggregate', 'DISTINCT date' took '1800 ms' con un' Agregado de flujo'). 'Oracle' y' MySQL' saltaban sobre los distintos campos en el índice, 'SQL Server' no lo hace. – Quassnoi
Debe seleccionar date_only distinto después de que se haya creado un índice en él. –
'@ Remus': Creé un índice, y el optimizador lo usó. – Quassnoi