sql查询性能不佳

时间:2015-04-07 13:31:53

标签: sql sql-server

我有一个SQL片段,它比较了最后两个记录,并在几秒钟内给出了datediff,但是我的方式很慢,根据控制器ID的数量,执行最多需要20秒才能执行我需要检查一下。

这样做更有效的方法是什么?

select
    T.controllerID,
    datediff(ss, T.Max_dtReading, T1.Max_dtReading) As ElaspedTime
from
    (select
        controllerID,
        max(dtReading) as Max_dtReading
     from 
        ReaderData
     where 
        CardID = 'FFFFFFF0' AND (controllerID in(2,13,28,30,37,40))
     group by 
        controllerID) as T
outer apply
    (select 
         max(T1.dtReading) as Max_dtReading
     from
         ReaderData as T1
     where
         T1.CardID = 'FFFFFFF0' AND (controllerID in(2,13,28,30,37,40))
         and T1.controllerID = T.controllerID
         and T1.dtReading < T.Max_dtReading) as T1

3 个答案:

答案 0 :(得分:3)

我可能会为此建议条件聚合:

select controllerID,
       datediff(second, max(dtReading), min(dtReading)
               ) As ElaspedTime
from (select controllerID, dtReading,
             row_number() over (partition by controllerID order by dtReading desc) as seqnum
      from ReaderData
      where CardID = 'FFFFFFF0' AND 
            controllerID in (2, 13, 28, 30, 37, 40)
     ) r
where seqnum <= 2
group by controllerID

答案 1 :(得分:1)

;WITH CTE AS
(select controllerID
        ,dtReading
        ,ROW_NUMBER() OVER (PARTITION BY controllerID ORDER BY dtReading DESC) rn
    from  ReaderData
    where CardID = 'FFFFFFF0' 
     AND  controllerID IN (2,13,28,30,37,40)
) 
select C1.controllerID
      ,datediff(ss, C1.dtReading, C2.dtReading) As ElaspedTime
from CTE C1 
LEFT JOIN CTE C2 ON C1.controllerID = C2.controllerID
                AND C1.rn = 1
                AND C1.rn < C2.rn 

答案 2 :(得分:1)

您可以使用ROW_NUMBER()来查找具有2个最高dtReading值的记录,然后将它们连接在一起以计算差异:

;WITH CTE AS (
    SLEECT controllerID, dtReading,
           ROW_NUMBER() OVER (PARTITION BY controllerID 
                              ORDER BY dtReading DESC) AS rn        
    FROM ReaderData
    WHERE CardID = 'FFFFFFF0' AND (controllerID IN (2,13,28,30,37,40))
)    
SELECT c1.controllerID, 
       DATEDIFF(ss, c1.dtReading, c2.dtReading) AS ElaspedTime
FROM CTE c1
INNER JOIN CTE c2 ON (c1.controllerID = c2.controllerID) 
                     AND c1.rn = 1 AND c2.rn = 2