如何在Sql Server中构造group by的索引

Cra*_*aig 7 sql sql-server indexing group-by

以下简单查询需要很长时间(几分钟)才能执行.

我有一个索引:

create index IX on [fctWMAUA] (SourceSystemKey, AsAtDateKey)
Run Code Online (Sandbox Code Playgroud)
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]
Run Code Online (Sandbox Code Playgroud)

统计数据如下:

  • 逻辑读取1827978
  • 物理读取1113
  • 预读1806459

采用完全相同的查询并重新格式化如下给我这些统计信息:

  • 逻辑读数36
  • 物理读数0
  • 预读0

执行需要31毫秒.

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 */
Run Code Online (Sandbox Code Playgroud)

如何快速制作完成该组的索引?

And*_*mar 1

尝试告诉 SQL Server 使用索引:

...
FROM [fctWMAUA] (NOLOCK, INDEX(IX)) AS [t0]
...
Run Code Online (Sandbox Code Playgroud)

确保表的统计信息是最新的:

UPDATE STATISTICS [fctWMAUA]
Run Code Online (Sandbox Code Playgroud)

为了获得更好的答案,请打开两个查询的显示计划:

SET SHOWPLAN_TEXT ON
Run Code Online (Sandbox Code Playgroud)

并将结果添加到您的问题中。

您还可以编写不带 GROUP BY 的查询。例如,您可以使用独占 LEFT JOIN 排除日期较旧的行:

select cur.SourceSystemKey, cur.date
from fctWMAUA cur
left join fctWMAUA next
    on next.SourceSystemKey = next.SourceSystemKey
    and next.date > cur.date
where next.SourceSystemKey is null
and cur.SourceSystemKey in (1,2,3,4,5,6,7,8,9)
Run Code Online (Sandbox Code Playgroud)

这可能快得令人惊讶,但我认为它无法击败 UNION。