The following simple query takes a very long time (several minutes) to execute.
I have an index:
create index IX on [fctWMAUA] (SourceSystemKey, AsAtDateKey)
SELECT MAX([t0].[AsAtDateKey]) AS [Date], [t0].[SourceSystemKey] AS [SourceSystem]
FROM [fctWMAUA] (NOLOCK) AS [t0]
WHERE SourceSystemKey in (1,2,3,4,5,6,7,8,9)
GROUP BY [t0].[SourceSystemKey]
The statistics are as follows:
- logical reads 1827978
- physical reads 1113
- read aheads 1806459
Taking that exact same query and reformatting it as follows gives me these statistics:
- logical reads 36
- physical reads 0
- read aheads 0
It takes 31ms to execute.
SELECT MAX([t0].[AsAtDateKey]) AS [Date], [t0].[SourceSystemKey] AS [SourceSystem]
FROM [fctWMAUA] (NOLOCK) AS [t0]
WHERE SourceSystemKey = 1
GROUP BY [t0].[SourceSystemKey]
UNION
SELECT MAX([t0].[AsAtDateKey]) AS [Date], [t0].[SourceSystemKey] AS [SourceSystem]
FROM [fctWMAUA] (NOLOCK) AS [t0]
WHERE SourceSystemKey = 2
GROUP BY [t0].[SourceSystemKey]
UNION
SELECT MAX([t0].[AsAtDateKey]) AS [Date], [t0].[SourceSystemKey] AS [SourceSystem]
FROM [fctWMAUA] (NOLOCK) AS [t0]
WHERE SourceSystemKey = 3
GROUP BY [t0].[SourceSystemKey]
/* AND SO ON TO 9 */
How do I make an index that does the group by quickly?
Try to tell SQL Server to use the index:
Make sure the statistics for the table are up to date:
For better answers, turn on the showplan for both queries:
and add the results to your question.
You can also write the query without a GROUP BY. For example, you can use an exclusive LEFT JOIN excluding rows with older dates:
This can be surprisingly fast, but I don’t think it could beat the UNION.