2016-09-18 14 views
1

内部クエリを減らしてクエリのパフォーマンスを向上させようとしています。SQL Server:内部クエリのパフォーマンスを向上させる

ReasonTUMを返すので、最初のものが必要になります。

しかし、ReasonTUMのケースを使用して番号を返すようにしたいと思います。

どうすればこの問題を解決できますか?元のクエリでmms.sMachineStateNameを参照しようとしましたが、その列は検出されません。

私が考えることができる唯一の別の方法は、別のサブクエリを使用することですが、これはジョインのために300行を返すのに約1分かかることです。

declare @ReportingStart datetime = '20160917 07:00' 
declare @ReportingEnd datetime = '20160918 07:00' 

SELECT 
     [sWorkcellDescription] 
     ,[tStart] 
     ,[dDurationSeconds]/60 as Duration_m 
     ,[sStateDescription] 
     ,datepart(hh,tstart) as myHr 
     ,case when convert(time,tstart)< '07:00' then dateadd(dd,-1,convert(date,tstart)) else convert(date,tstart) end as myDate, 
     cast(dateadd(hour,datepart(hh,tstart),0) as datetime) as dispTime, 
     (
      select top 1 mms.sMachineStateName 
      from OEEEvent oe 
      inner join RSBizWare.dbo.OEEConfigEvent ce on oe.lOEEConfigEventId = ce.lOEEConfigEventId 
      inner join RSBizWare.dbo.OEELOVCodeVal rs on oe.sStartVal = rs.sDescription and ce.lOEEIntRSSqlId=rs.lOEELOVCodeId 
      inner join RSBizWare.dbo.OEEStateConfig mms on rs.lMachineState = mms.lOEEStateConfigId 
      where qq.tStart between oe.tStart and oe.tEnd and oe.sPartId='Ore-Hoist' 
      order by qq.tStart asc 
     ) as ReasonTUM, 
       (
      select top 1 case 
     when mms.sMachineStateName = 'Production' then '1' 
     when mms.sMachineStateName = 'Unscheduled Production' then '2' 
     when mms.sMachineStateName = 'Idle time' then '3' 
     when mms.sMachineStateName = 'Opportune Maintenance' then '4' 
     when mms.sMachineStateName = 'Planned External Downtime' then '5' 
     when mms.sMachineStateName = 'Planned External Downtime' then '5' 
     when mms.sMachineStateName = 'Planned Maintenance Mechanical' then '5' 
     when mms.sMachineStateName = 'Planned Maintenance Electrical' then '6' 
     when mms.sMachineStateName = 'Unplanned Downtime Operational' then '7' 
     when mms.sMachineStateName = 'Unplanned Downtime Mechanical' then '8' 
     when mms.sMachineStateName = 'Unplanned Downtime Electrical' then '9' 
     else '99' end 
      from OEEEvent oe 
      inner join RSBizWare.dbo.OEEConfigEvent ce on oe.lOEEConfigEventId = ce.lOEEConfigEventId 
      inner join RSBizWare.dbo.OEELOVCodeVal rs on oe.sStartVal = rs.sDescription and ce.lOEEIntRSSqlId=rs.lOEELOVCodeId 
      inner join RSBizWare.dbo.OEEStateConfig mms on rs.lMachineState = mms.lOEEStateConfigId 
      where qq.tStart between oe.tStart and oe.tEnd and oe.sPartId='Ore-Hoist' 
     ) as rank 
FROM 
    [RSBizWare].[dbo].[OEEQStateData] qq 
WHERE 
    (tstart >= @ReportingStart AND tStart < @ReportingEnd) 
    AND sWorkcellDescription = 'Hoisting' 
    AND dDurationSeconds > 5 
ORDER BY 
    tStart ASC 
+0

を呼び出さないように? JOINは一般的には1)セットとして実行できない場合(内部クエリをJOIN自身に変換するための簡単な方法)、または2)クエリの適切なインデックスが見つからない場合には、通常遅くなります。 – user2864740

+0

実行計画を読み込みます。 – qxg

答えて

3

使用OUTER APPLYは、内側のクエリが外側に関係しない方法sub-query二回

SELECT [sworkcelldescription], 
     [tstart], 
     [ddurationseconds]/60         AS Duration_m, 
     [sstatedescription], 
     Datepart(hh, tstart)          AS myHr, 
     CASE 
     WHEN CONVERT(TIME, tstart) < '07:00' THEN Dateadd(dd, -1, 
                CONVERT(DATE, tstart 
                )) 
     ELSE CONVERT(DATE, tstart) 
     END              AS myDate, 
     Cast(Dateadd(hour, Datepart(hh, tstart), 0) AS DATETIME) AS dispTime, 
     OA.reasontum, 
     OA.[rank] 
FROM [RSBizWare].[dbo].[oeeqstatedata] qq 
     OUTER apply (SELECT TOP 1 mms.smachinestatename, 
           CASE mms.smachinestatename 
            WHEN 'Production' THEN '1' 
            WHEN 'Unscheduled Production' THEN '2' 
            WHEN 'Idle time' THEN '3' 
            WHEN 'Opportune Maintenance' THEN '4' 
            WHEN 'Planned External Downtime' THEN '5' 
            WHEN 'Planned External Downtime' THEN '5' 
            WHEN 'Planned Maintenance Mechanical' THEN '5' 
            WHEN 'Planned Maintenance Electrical' THEN '6' 
            WHEN 'Unplanned Downtime Operational' THEN '7' 
            WHEN 'Unplanned Downtime Mechanical' THEN '8' 
            WHEN 'Unplanned Downtime Electrical' THEN '9' 
            ELSE '99' 
           END AS [Rank] 
        FROM oeeevent oe 
          INNER JOIN rsbizware.dbo.oeeconfigevent ce 
            ON oe.loeeconfigeventid = 
             ce.loeeconfigeventid 
          INNER JOIN rsbizware.dbo.oeelovcodeval rs 
            ON oe.sstartval = rs.sdescription 
             AND ce.loeeintrssqlid = rs.loeelovcodeid 
          INNER JOIN rsbizware.dbo.oeestateconfig mms 
            ON rs.lmachinestate = mms.loeestateconfigid 
        WHERE qq.tstart BETWEEN oe.tstart AND oe.tend 
          AND oe.spartid = 'Ore-Hoist' 
        ORDER BY qq.tstart ASC) OA 
WHERE (tstart >= @ReportingStart 
     AND tstart < @ReportingEnd) 
     AND sworkcelldescription = 'Hoisting' 
     AND ddurationseconds > 5 
ORDER BY tstart ASC 
+0

両方の質問がTOP 1を使用してレコードを選択していますが、ORDER BYで1とORDER BYで両方の値が選択されている場合、両方とも同じ結果が必要な場合はその罰金、それ以外の場合は同じ結果を返します。 – Susang

+0

@Suraz - 間違っていない場合OPは両方のサブクエリでOrder by –

+0

@Prdp - クエリのパフォーマンスは59sから28sになりました!ありがとうございました – GlenCloncurry

関連する問題