获取大型数据集中第一个和最后一个记录 ID 的最有效查询
most efficient query to get the first and last record id in a large dataset
我需要针对大型数据集编写查询以获取第一条和最后一条记录 ID,以及第一条记录的创建时间。数据样本如下:
在上述情况下,如果将类别 "Blue" 作为参数传递到查询中,我将期望 return "A12, 13:00, E66" 作为查询结果。
我可以使用聚合函数从数据集中获取最大和最小时间,并加入以获取第一条和最后一条记录。但只是想知道是否有更有效的方法来实现相同的输出?
我的建议是通过比较执行计划并在类别 ID(用于查找)和时间(用于排序)列上放置索引来尝试减少 scan/seek 操作的数量。
如果您有 SQL Server 2008 或更高版本,您可以使用以下内容,这需要两个 scans/seeks:
Declare @CategoryID As Varchar(16)
Set @CategoryID = 'Blue'
Select
First_Record.RecordID,
First_Record.CreatedTime,
Last_Record.RecordID
From
(
Select Top 1
RecordID,
CreatedTime
From
<Table>
Where
CategoryID = @CategoryID
Order By
CreatedTime Asc
) First_Record
Cross Apply
(
Select Top 1
RecordID
From
<Table>
Where
CategoryID = @CategoryID
Order By
CreatedTime Desc
) Last_Record
如果你有 SQL Server 2012 或更高版本,你可以编写以下内容,只需要一个 scan/seek:
Select Top 1
First_Value(RecordID) Over (Partition By CategoryID Order By CreatedTime Asc),
First_Value(CreatedTime) Over (Partition By CategoryID Order By CreatedTime Asc),
First_Value(RecordID) Over (Partition By CategoryID Order By CreatedTime Desc)
From
<Table>
Where
CategoryID = @CategoryID
我需要针对大型数据集编写查询以获取第一条和最后一条记录 ID,以及第一条记录的创建时间。数据样本如下:
在上述情况下,如果将类别 "Blue" 作为参数传递到查询中,我将期望 return "A12, 13:00, E66" 作为查询结果。 我可以使用聚合函数从数据集中获取最大和最小时间,并加入以获取第一条和最后一条记录。但只是想知道是否有更有效的方法来实现相同的输出?
我的建议是通过比较执行计划并在类别 ID(用于查找)和时间(用于排序)列上放置索引来尝试减少 scan/seek 操作的数量。
如果您有 SQL Server 2008 或更高版本,您可以使用以下内容,这需要两个 scans/seeks:
Declare @CategoryID As Varchar(16)
Set @CategoryID = 'Blue'
Select
First_Record.RecordID,
First_Record.CreatedTime,
Last_Record.RecordID
From
(
Select Top 1
RecordID,
CreatedTime
From
<Table>
Where
CategoryID = @CategoryID
Order By
CreatedTime Asc
) First_Record
Cross Apply
(
Select Top 1
RecordID
From
<Table>
Where
CategoryID = @CategoryID
Order By
CreatedTime Desc
) Last_Record
如果你有 SQL Server 2012 或更高版本,你可以编写以下内容,只需要一个 scan/seek:
Select Top 1
First_Value(RecordID) Over (Partition By CategoryID Order By CreatedTime Asc),
First_Value(CreatedTime) Over (Partition By CategoryID Order By CreatedTime Asc),
First_Value(RecordID) Over (Partition By CategoryID Order By CreatedTime Desc)
From
<Table>
Where
CategoryID = @CategoryID