Devo admitir que não tinha visto a conversão de piso flutuante mostrada por Matt antes. Eu tive que testar isso.
Eu testei um select puro (que retornará Data e Hora, e não é o que queremos), a solução reinante aqui (floor-float), um 'ingênuo' comum mencionado aqui (stringconvert) e o mencionado aqui que eu estava usando (como eu pensei que era o mais rápido).
Eu testei as consultas em um servidor de teste MS SQL Server 2005 rodando em um servidor Win 2003 SP2 com uma CPU Xeon 3GHz rodando em memória máxima (32 bits, ou seja, cerca de 3,5 Gb). É noite onde estou, então a máquina está em marcha lenta quase sem carga. Eu tenho tudo para mim.
Aqui está o log da minha seleção de execução de teste em uma grande tabela contendo carimbos de data/hora variando até o nível de milissegundos. Esse conjunto de dados específico inclui datas que variam mais de 2,5 anos. A tabela em si tem mais de 130 milhões de linhas, então é por isso que restrinjo ao primeiro milhão.
SELECT TOP 1000000 CRETS FROM tblMeasureLogv2
SELECT TOP 1000000 CAST(FLOOR(CAST(CRETS AS FLOAT)) AS DATETIME) FROM tblMeasureLogv2
SELECT TOP 1000000 CONVERT(DATETIME, CONVERT(VARCHAR(10), CRETS, 120) , 120) FROM tblMeasureLogv2
SELECT TOP 1000000 DATEADD(DAY, DATEDIFF(DAY, 0, CRETS), 0) FROM tblMeasureLogv2
Tempo de análise e compilação do SQL Server:tempo de CPU =0 ms, tempo decorrido =1 ms.
(1000000 linhas afetadas) Tabela 'tblMeasureLogv2'. Contagem de varredura 1, leituras lógicas 4752, leituras físicas 0, leituras antecipadas 0, leituras lógicas lob 0, leituras físicas lob 0, leituras antecipadas lob 0.
Tempos de execução do SQL Server:tempo de CPU =422 ms, tempo decorrido =33803 ms.
(1000000 linhas afetadas) Tabela 'tblMeasureLogv2'. Contagem de varredura 1, leituras lógicas 4752, leituras físicas 0, leituras antecipadas 0, leituras lógicas lob 0, leituras físicas lob 0, leituras antecipadas lob 0.
Tempos de execução do SQL Server:tempo de CPU =625 ms, tempo decorrido =33545 ms.
(1000000 linhas afetadas) Tabela 'tblMeasureLogv2'. Contagem de varredura 1, leituras lógicas 4752, leituras físicas 0, leituras antecipadas 0, leituras lógicas lob 0, leituras físicas lob 0, leituras antecipadas lob 0.
Tempos de execução do SQL Server:tempo de CPU =1953 ms, tempo decorrido =33843 ms.
(1000000 linhas afetadas) Tabela 'tblMeasureLogv2'. Contagem de varredura 1, leituras lógicas 4752, leituras físicas 0, leituras antecipadas 0, leituras lógicas lob 0, leituras físicas lob 0, leituras antecipadas lob 0.
Tempos de execução do SQL Server:tempo de CPU =531 ms, tempo decorrido =33440 ms. Tempo de análise e compilação do SQL Server:tempo de CPU =0 ms, tempo decorrido =1 ms.
Tempos de execução do SQL Server:tempo de CPU =0 ms, tempo decorrido =1 ms.
O que estamos vendo aqui?
Vamos nos concentrar no tempo de CPU (estamos olhando para a conversão), e podemos ver que temos os seguintes números:
Pure-Select: 422
Floor-cast: 625
String-conv: 1953
DateAdd: 531
A partir disso, parece-me que o DateAdd (pelo menos neste caso específico) é um pouco mais rápido que o método floor-cast.
Antes de ir lá, fiz esse teste várias vezes, com a ordem das consultas alterada, resultados iguais.
Isso é algo estranho no meu servidor, ou o quê?