sql server:索引视图包含每组最大的行

Posted

技术标签:

【中文标题】sql server:索引视图包含每组最大的行【英文标题】:sql server: indexed view containing greatest row per group 【发布时间】:2013-04-12 04:43:34 【问题描述】:

我正在尝试创建一个索引视图,以计算我数据库中表的每组最大 n。不过,我已经为视图尝试了三种不同的查询,但它们似乎都是 sql server 不允许的。该表只是一个文件列表,每个文件都有一个 ID、一个用户 ID 和一个日期,我试图为每个用户找到最新的文件。

我尝试了here 的 2 条建议,但它们给了我错误,说我不允许在索引视图中进行分组或外部联接。我将在此处复制我的实现,以便您查看。

select f1.id, f1.userid, f1.filedate
from files f1
inner join(
   select userid, max(filedate) as maxDate
   from files
   group by userid
) as f2
on f1.userid = f2.userid and f1.maxdate = f2.maxdate

select f1.id, f1.userid, f1.filedate
from files f1
left outer join files f2
on (f1.userid = f2.userid and f1.filedate < f2.filedate)
where f2.id is null;

这两个查询都有效,但在视图上创建索引失败,因为它说不允许分组和外连接。

我也试过

SELECT f1.id, f1.userid, f1.filedate FROM [dbo].[DiagnosticFiles] as f1
WHERE NOT EXISTS (
   SELECT f1.id FROM [dbo].[DiagnosticFiles] as f2 INNER JOIN [dbo].[DiagnosticFiles] as f3 ON f2.userid = f3.userid
WHERE f1.id = f2.id AND f2.FileDate < f3.FileDate)

当我尝试将其添加到索引时,它说不允许子查询

我知道如何仅使用内部连接来执行此操作,但问题是它似乎需要 n-1 个连接,其中 n 是单个用户 ID 拥有的最大文件数。这是基本查询

SELECT DISTINCT f1.id, f1.userid, f1.filedate
FROM FILES f1
INNER JOIN files f2
ON (f1.userid = f2.userid and f1.filedate > f2.filedate)

这仅适用于任何给定用户 ID 最多 2 行的情况。 See Here。如果我将此添加到查询的末尾

INNER JOIN files f3
ON (f2.userid = f3.userid and f2.filedate > f3.filedate)

然后每个用户最多可以处理 3 个文件,但您会发现问题。

是否有合理的方法为此类查询创建索引视图?

谢谢。

编辑:此外,如果没有办法进行索引视图,并且我将其保留为基本上每次都进行查询的未索引视图,那么对于大量行来说这会非常慢,并且可能在每个用户数百行?我正计划在 userid 和 filedate 上创建一些非聚集索引

【问题讨论】:

【参考方案1】:

不,那不可能。如果是这样就太好了。我建议您在http://connect.microsoft.com 上为您可以找到的所有索引视图票(有些是我的)投票,以获得该功能的优先权。

您的一些想法也因不允许自联接这一事实而失败。列出允许什么不允许什么确实更快。

您最多可以实现查询的一部分:

   select userid, max(filedate) as maxDate
   from files
   group by userid

并在文件上添加一个有用的索引以重新加入它。总体而言,这可能会为您提供非常便宜的查询。

【讨论】:

这会比只将其中一个查询保留为未索引视图并正确索引原始表更好吗? 是的,因为未索引的视图根本没有帮助。查看查询计划并比较它们以确定影响。

以上是关于sql server:索引视图包含每组最大的行的主要内容,如果未能解决你的问题,请参考以下文章

使用R查找包含最大值的行索引

SQL Server和Oracle数据库索引介绍

选择每组的最大行数 - 熊猫性能问题

Python:删除每组中具有最大值的行

SQL:查找每组的最大记录[重复]

SQL:查找每组的最大记录[重复]