2013-08-07 38 views
0

我有以下查询:优化SQL子查询的最大价值

SELECT dlp.ParamID ParamID, dp.ParamName ParamName, dlp.LocID LocationID, ml.LocName LocationName , di.Entered_On DateEntered, dlp.FreqDays Frequency 
    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 
    WHERE ((dlp.FreqDays IS NOT NULL) AND di.Entered_On < (GETUTCDATE() - dlp.FreqDays)) 
    AND 
    di.Entered_On = (select max(Entered_On) from data_Input where LocId = dlp.LocID 
        and ParamId = dlp.ParamID) 

我需要如何优化这个查询援助。瓶颈似乎与followng:

di.Entered_On = (select max(Entered_On) from data_Input where LocId = dlp.LocID 
        and ParamId = dlp.ParamID) 

注意,对于一个给定的Enter_On,我需要根据LOCID和芳族聚酰胺的最大Entered_On日期。

我尝试以下,但没有得到预期的结果:

 SELECT * FROM 
    (
     SELECT dlp.ParamID ParamID, dp.ParamName ParamName, dlp.LocID LocationID, ml.LocName LocationName, di.Entered_On DateEntered, dlp.FreqDays Frequency,  
     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 
     WHERE dlp.FreqDays IS NOT NULL  
     ) as a WHERE a.RowNum = 1 and DateEntered < (GETUTCDATE() - Frequency) 

回答

0

我认为你可以在di表(在这里做一个子查询)的窗口函数替换它。需要注意的是where子句不是在子查询,因为这影响用于max()行(这大概是你的第二个查询的问题):使用这样

SELECT dlp.ParamID ParamID, dp.ParamName ParamName, dlp.LocID LocationID, ml.LocName LocationName , di.Entered_On DateEntered, dlp.FreqDays Frequency 
    FROM data_LocParams dlp 
    INNER JOIN (select di.*, 
         max(Entered_On) over (partition by LocId, ParamId) as maxeo 
       from data_Input di 
       ) 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 
    WHERE (dlp.FreqDays IS NOT NULL) AND di.Entered_On = di.maxeo and 
      di.Entered_On < (GETUTCDATE() - dlp.FreqDays) 
0

尝试 -

select ParamID, 
    ParamName, 
    LocationID, 
    LocationName, 
    DateEntered, 
    Frequency 
from (SELECT dlp.ParamID ParamID, 
     dp.ParamName ParamName, 
     dlp.LocID LocationID, 
     ml.LocName LocationName, 
     di.Entered_On DateEntered, 
     dlp.FreqDays Frequency, 
     row_number() over(partition by di.LocID order by di.Entered_On desc) as rn 
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 
WHERE ((dlp.FreqDays IS NOT NULL) AND di.Entered_On < (GETUTCDATE() - dlp.FreqDays)) 
) as T 
where rn = 1