Eu executo um banco de dados SQL Server 2016 onde tenho a seguinte tabela com mais de 100 milhões de linhas:
StationId | ParameterId | DateTime | Value
1 | 2 | 2020-02-04 15:00:000 | 5.20
1 | 2 | 2020-02-04 14:00:000 | 5.20
1 | 2 | 2020-02-04 13:00:000 | 5.20
1 | 3 | 2020-02-04 15:00:000 | 2.81
1 | 3 | 2020-02-04 14:00:000 | 2.81
1 | 4 | 2020-02-04 15:00:000 | 5.23
2 | 2 | 2020-02-04 15:00:000 | 3.70
2 | 4 | 2020-02-04 15:00:000 | 12.20
3 | 2 | 2020-02-04 15:00:000 | 1.10
Esta tabela possui um índice clusterizado para StationId, ParameterId e DateTime, nesta ordem, todos crescentes.
O que eu preciso é, para cada par exclusivo StationId - ParameterId, retornar o valor mais recente da coluna DateTime:
StationId | ParameterId | LastDate
1 | 2 | 2020-02-04 15:00:000
1 | 3 | 2020-02-04 15:00:000
1 | 4 | 2020-02-04 15:00:000
2 | 2 | 2020-02-04 15:00:000
2 | 4 | 2020-02-04 15:00:000
3 | 2 | 2020-02-04 15:00:000
O que estou fazendo agora é a seguinte consulta, que leva cerca de 90 a 120 segundos para ser executada:
SELECT StationId, ParameterId, MAX(DateTime) AS LastDate
FROM MyTable WITH (NOLOCK)
GROUP BY StationId, ParameterId
Também vi muitos posts sugerindo o seguinte, que leva mais de 10 minutos para ser executado:
SELECT StationId, ParameterId, DateTime AS LastDate
FROM
(
SELECT StationId, ParameterId, DateTime
,ROW_NUMBER() OVER (PARTITION BY StationId,ParameterIdORDER BY DateTime DESC) as row_num
FROM MyTable WITH (NOLOCK)
)
WHERE row_num = 1
Mesmo no melhor caso (usando a cláusula GROUP BY e a função agregada MAX), o plano de execução não indica uma busca de índice:
Gostaria de saber se existe uma maneira melhor de realizar essa consulta (ou construir o índice) para obter um melhor tempo de execução.