Ped*_*ini 19 index sql-server optimization greatest-n-per-group sql-server-2016
我运行了一个 SQL Server 2016 数据库,其中有一个包含 100 多万行的下表:
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
Run Code Online (Sandbox Code Playgroud)
该表具有 StationId、ParameterId 和 DateTime 的聚集索引,按此顺序,全部升序。
我需要的是,对于每个唯一的对 StationId - ParameterId,从 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
Run Code Online (Sandbox Code Playgroud)
我现在正在做的是以下查询,运行大约需要 90 到 120 秒:
SELECT StationId, ParameterId, MAX(DateTime) AS LastDate
FROM MyTable WITH (NOLOCK)
GROUP BY StationId, ParameterId
Run Code Online (Sandbox Code Playgroud)
我还看到许多帖子提出以下建议,运行时间超过 10 分钟:
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
Run Code Online (Sandbox Code Playgroud)
即使在最好的情况下(使用 GROUP BY 子句和 MAX 聚合函数),执行计划也不指示索引查找:
我想知道是否有更好的方法来执行此查询(或构建索引)以实现更好的执行时间。
Dav*_*oft 25
如果您有足够少的 (StationID, ParameterID) 对,请尝试如下查询:
select StationID, ParameterID, m.DateTime LastDate
from StationParameter sp
cross apply
(
select top 1 DateTime
from MyTable
where StationID = sp.StationID
and ParameterID = sp.ParameterID
order by DateTime desc
) m
Run Code Online (Sandbox Code Playgroud)
为了使 SQL Server 能够执行查找,DateTime
为每个 (StationID,ParameterID) 对寻找最新的。
只有在 (StationID, ParameterID, DateTime) 上的聚集索引,SQL Server 无法在不扫描索引的叶级别的情况下发现不同的 (StationID, ParameterID) 对,并且它可以在扫描时找到最大的 DateTime。
同样在 100M+ 行时,这个表可能更适合作为聚集列存储而不是 BTree 聚集索引。
归档时间: |
|
查看次数: |
27871 次 |
最近记录: |