我有以下查询。我做的部分
select for max(Entered_On).....
花费的时间最长。如果我注释掉原因,它会快速运行。
Select dlp.ParamID, dp.ParamName
from data_LocP dlp
inner join data_In di on dlp.LocID = di.LocID
inner join data_Parms dp on dp.ParamID = di.ParamID
inner join map_Loc ml on ml.LocId = dlp.LocId
where di.Entered_On = (select max(Entered_On ) from data_In where LocId = dlp.LocID
and ParamId = dlp.ParamID)
我想知道是否有一种方法可以优化此查询,因为我获得Max(Entered_On)的部分花费的时间最长。作为一个FYI,我需要将Entered_On作为给定LocId和ParamId的最大日期。
这是一个更加扩展的代码但不提供max:
select * FROM
(
SELECT dlp.ParamID, dp.ParamName, dlp.LocID, ml.LocName , di.Entered_On, (GETUTCDATE() - dlp.FreqDays) DueDate, dlp.FreqDays,
a.CompanyId, a.SiteID,
ROW_NUMBER() OVER (PARTITION BY dlp.LocId, dlp.ParamID
ORDER BY di.Entered_On DESC)
as RowNum
from data_LocParams dlp
inner join data_Input di on dlp.LocID = di.LocID
inner join data_Parameters dp on dp.ParamID = di.ParamID
inner join map_Locations ml on ml.LocId = dlp.LocId
left join
(
select ml.LocId,ms.CompanyId, ms.SiteId
from map_Sites ms
join map_WaterSystems mw
on ms.SiteID = mw.SiteID
join map_Locations ml
on ml.SysID = mw.SysID
) a
on a.LocId = dlp.LocID
where dlp.FreqDays is not null AND dlp.FreqDays <> ''
) as a WHERE a.RowNum = 1 and Entered_On < (GETUTCDATE() - FreqDays)
答案 0 :(得分:4)
尝试使用ROW_NUMBER()
代替相关子查询:
SELECT * FROM (
SELECT dlp.ParamID, dp.ParamName,
ROW_NUMBER() OVER (PARTITION BY dlp.LocId, dlp.ParamID
ORDER BY di.Entered_On) as RowNum
FROM data_LocP dlp
JOIN data_In di on dlp.LocID = di.LocID
JOIN data_Parms dp on dp.ParamID = di.ParamID
JOIN map_Loc ml on ml.LocId = dlp.LocId
) WHERE RowNum = 1
如果您有多条记录可以匹配相同的Entered_On
值,请使用RANK()
代替ROW_NUMBER()
。
答案 1 :(得分:1)
除了对SQL SELECT的任何更改外,请尝试以Entered_On
顺序构建一个DESC
的索引。这应该有助于任何需要对Entered_On DESC进行排序或拉出Entered_On的MAX的查询。
CREATE NONCLUSTERED INDEX idx_entered_on ON data_in
(
LocId, ParamId, Entered_On DESC
)
答案 2 :(得分:0)
您说“我需要将Entered_On作为给定LocId和ParamId的最大日期”,但您没有为这些字段指定任何值。类似的东西:
where locId = something
and ParamId = something
主查询和子查询中的将为您提供您想要的内容,并且可以非常快速地完成。