2013-08-06 92 views
0

我有以下查询。我做的部分SQL优化查询以获取最大值

 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) 

我想知道如果有一种方法来优化这个查询,那是我得到的最大(Entered_On)花费时间最长的部分。作为参考,我需要Entered_On是给定LocId和ParamId的最大日期。

这里是一个更扩展的代码,但没有给出最大:

 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) 

回答

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()

+0

为什么不使用max(entered_on)而不是row_number? – Wirus

+0

@Wirus为每个记录提供每个LocId和Paramid的最大值,并且您不能分辨出与最大值相关的参数名(entered_on) –

+0

@Conrad - 我放置了一个更加扩展的代码(请看上面),但似乎我无法得到它的工作基于ROW_NUMBER()..它运行,但我没有得到一个给定的LocId对一个给定的LocId ParamID。你知道我在做什么错吗.. –

0

你说“我需要Entered_On是给定LocId和ParamId的最大日期”,但是你没有为这些字段指定任何值。例如:

where locId = something 
and ParamId = something 

在主查询和子查询中都会得到你所说的你想要的,并且会很快做到。

1

除了对SQL SELECT进行的任何更改之外,请尝试按DESC的顺序与Entered_On建立索引。这应该有助于任何需要在Entered_On DESC上排序的查询或拉取Entered_On的MAX。

CREATE NONCLUSTERED INDEX idx_entered_on ON data_in 
(
    LocId, ParamId, Entered_On DESC 
)