Нужно оптимизировать производительность этого оператора SQL Server - PullRequest
0 голосов
/ 14 июля 2011

Я знаю, что это сложная задача, чтобы попросить сделать что-то быстрое из этого оператора SQL, но я был бы признателен, если бы кто-то взглянул и, возможно, предложил, как я могу его оптимизировать?

Следующий запрос генерируется сценарием ASP NET (поэтому я не просто прописываю значения в нем). Хотя я сделал «развернуть» первый оператор SELECT для удобства чтения:

WITH 
valDiff0 AS (SELECT datediff(second,
  CASE  
   WHEN '2011-06-06 00:00:00' < [inTime] THEN [inTime]  
   ELSE '2011-06-06 00:00:00' 
  END, 
  CASE  
   WHEN isdate([outTime]) = 1 THEN   
     CASE    
      WHEN '2011-06-06 23:59:59' > [outTime] THEN [outTime]
      ELSE '2011-06-06 23:59:59'   
     END  
   ELSE
     CASE    
      WHEN '2011-06-06 23:59:59' > [inTime] + 604800 THEN [inTime] + 604800    
      ELSE '2011-06-06 23:59:59'   
     END 
   END)  
AS v1 FROM [dbo].[Info] WHERE   
   [cName] LIKE 'T%' 
   AND [b] <> 0 
   AND CONVERT(INT, [evt]) & 7 = 4 
   AND isdate([inTime]) = 1 
   AND  [inTime] <= '2011-06-06 23:59:59' 
   AND  [outTime] >= '2011-06-06 00:00:00'),

valDiff1 AS (
  SELECT datediff(second, CASE  WHEN '2011-06-07 00:00:00' < [inTime] THEN [inTime]  ELSE '2011-06-07 00:00:00' END, CASE  WHEN isdate([outTime]) = 1 THEN   CASE    WHEN '2011-06-07 23:59:59' > [outTime] THEN [outTime]    ELSE '2011-06-07 23:59:59'   END  else   case    WHEN '2011-06-07 23:59:59' > [inTime] + 604800 THEN [inTime] + 604800    ELSE '2011-06-07 23:59:59'   END END)  AS v1 FROM [dbo].[Info] WHERE   [cName] LIKE 'T%' AND [b] <> 0 AND CONVERT(INT, [evt]) & 7 = 4 AND isdate([inTime]) = 1 AND  [inTime] <= '2011-06-07 23:59:59' AND  [outTime] >= '2011-06-07 00:00:00'), 
valDiff2 AS (SELECT datediff(second,CASE  WHEN '2011-06-08 00:00:00' < [inTime] THEN [inTime]  ELSE '2011-06-08 00:00:00' END, CASE  WHEN isdate([outTime]) = 1 THEN   CASE    WHEN '2011-06-08 23:59:59' > [outTime] THEN [outTime]    ELSE '2011-06-08 23:59:59'   END  else   case    WHEN '2011-06-08 23:59:59' > [inTime] + 604800 THEN [inTime] + 604800    ELSE '2011-06-08 23:59:59'   END END)  AS v1 FROM [dbo].[Info] WHERE   [cName] LIKE 'T%' AND [b] <> 0 AND CONVERT(INT, [evt]) & 7 = 4 AND isdate([inTime]) = 1 AND  [inTime] <= '2011-06-08 23:59:59' AND  [outTime] >= '2011-06-08 00:00:00'), 
valDiff3 AS (SELECT datediff(second,CASE  WHEN '2011-06-09 00:00:00' < [inTime] THEN [inTime]  ELSE '2011-06-09 00:00:00' END, CASE  WHEN isdate([outTime]) = 1 THEN   CASE    WHEN '2011-06-09 23:59:59' > [outTime] THEN [outTime]    ELSE '2011-06-09 23:59:59'   END  else   case    WHEN '2011-06-09 23:59:59' > [inTime] + 604800 THEN [inTime] + 604800    ELSE '2011-06-09 23:59:59'   END END)  AS v1 FROM [dbo].[Info] WHERE   [cName] LIKE 'T%' AND [b] <> 0 AND CONVERT(INT, [evt]) & 7 = 4 AND isdate([inTime]) = 1 AND  [inTime] <= '2011-06-09 23:59:59' AND  [outTime] >= '2011-06-09 00:00:00'), 
valDiff4 AS (SELECT datediff(second,CASE  WHEN '2011-06-10 00:00:00' < [inTime] THEN [inTime]  ELSE '2011-06-10 00:00:00' END, CASE  WHEN isdate([outTime]) = 1 THEN   CASE    WHEN '2011-06-10 23:59:59' > [outTime] THEN [outTime]    ELSE '2011-06-10 23:59:59'   END  else   case    WHEN '2011-06-10 23:59:59' > [inTime] + 604800 THEN [inTime] + 604800    ELSE '2011-06-10 23:59:59'   END END)  AS v1 FROM [dbo].[Info] WHERE   [cName] LIKE 'T%' AND [b] <> 0 AND CONVERT(INT, [evt]) & 7 = 4 AND isdate([inTime]) = 1 AND  [inTime] <= '2011-06-10 23:59:59' AND  [outTime] >= '2011-06-10 00:00:00'), 
valDiff5 AS (SELECT datediff(second,CASE  WHEN '2011-06-11 00:00:00' < [inTime] THEN [inTime]  ELSE '2011-06-11 00:00:00' END, CASE  WHEN isdate([outTime]) = 1 THEN   CASE    WHEN '2011-06-11 23:59:59' > [outTime] THEN [outTime]    ELSE '2011-06-11 23:59:59'   END  else   case    WHEN '2011-06-11 23:59:59' > [inTime] + 604800 THEN [inTime] + 604800    ELSE '2011-06-11 23:59:59'   END END)  AS v1 FROM [dbo].[Info] WHERE   [cName] LIKE 'T%' AND [b] <> 0 AND CONVERT(INT, [evt]) & 7 = 4 AND isdate([inTime]) = 1 AND  [inTime] <= '2011-06-11 23:59:59' AND  [outTime] >= '2011-06-11 00:00:00'), 
valDiff6 AS (SELECT datediff(second,CASE  WHEN '2011-06-12 00:00:00' < [inTime] THEN [inTime]  ELSE '2011-06-12 00:00:00' END, CASE  WHEN isdate([outTime]) = 1 THEN   CASE    WHEN '2011-06-12 23:59:59' > [outTime] THEN [outTime]    ELSE '2011-06-12 23:59:59'   END  else   case    WHEN '2011-06-12 23:59:59' > [inTime] + 604800 THEN [inTime] + 604800    ELSE '2011-06-12 23:59:59'   END END)  AS v1 FROM [dbo].[Info] WHERE   [cName] LIKE 'T%' AND [b] <> 0 AND CONVERT(INT, [evt]) & 7 = 4 AND isdate([inTime]) = 1 AND  [inTime] <= '2011-06-12 23:59:59' AND  [outTime] >= '2011-06-12 00:00:00'), 
valDiff7 AS (SELECT datediff(second,CASE  WHEN '2011-06-13 00:00:00' < [inTime] THEN [inTime]  ELSE '2011-06-13 00:00:00' END, CASE  WHEN isdate([outTime]) = 1 THEN   CASE    WHEN '2011-06-13 23:59:59' > [outTime] THEN [outTime]    ELSE '2011-06-13 23:59:59'   END  else   case    WHEN '2011-06-13 23:59:59' > [inTime] + 604800 THEN [inTime] + 604800    ELSE '2011-06-13 23:59:59'   END END)  AS v1 FROM [dbo].[Info] WHERE   [cName] LIKE 'T%' AND [b] <> 0 AND CONVERT(INT, [evt]) & 7 = 4 AND isdate([inTime]) = 1 AND  [inTime] <= '2011-06-13 23:59:59' AND  [outTime] >= '2011-06-13 00:00:00'), 
valDiff8 AS (SELECT datediff(second,CASE  WHEN '2011-06-14 00:00:00' < [inTime] THEN [inTime]  ELSE '2011-06-14 00:00:00' END, CASE  WHEN isdate([outTime]) = 1 THEN   CASE    WHEN '2011-06-14 23:59:59' > [outTime] THEN [outTime]    ELSE '2011-06-14 23:59:59'   END  else   case    WHEN '2011-06-14 23:59:59' > [inTime] + 604800 THEN [inTime] + 604800    ELSE '2011-06-14 23:59:59'   END END)  AS v1 FROM [dbo].[Info] WHERE   [cName] LIKE 'T%' AND [b] <> 0 AND CONVERT(INT, [evt]) & 7 = 4 AND isdate([inTime]) = 1 AND  [inTime] <= '2011-06-14 23:59:59' AND  [outTime] >= '2011-06-14 00:00:00'), 
valDiff9 AS (SELECT datediff(second,CASE  WHEN '2011-06-15 00:00:00' < [inTime] THEN [inTime]  ELSE '2011-06-15 00:00:00' END, CASE  WHEN isdate([outTime]) = 1 THEN   CASE    WHEN '2011-06-15 23:59:59' > [outTime] THEN [outTime]    ELSE '2011-06-15 23:59:59'   END  else   case    WHEN '2011-06-15 23:59:59' > [inTime] + 604800 THEN [inTime] + 604800    ELSE '2011-06-15 23:59:59'   END END)  AS v1 FROM [dbo].[Info] WHERE   [cName] LIKE 'T%' AND [b] <> 0 AND CONVERT(INT, [evt]) & 7 = 4 AND isdate([inTime]) = 1 AND  [inTime] <= '2011-06-15 23:59:59' AND  [outTime] >= '2011-06-15 00:00:00'), 
valDiff10 AS (SELECT datediff(second,CASE  WHEN '2011-06-16 00:00:00' < [inTime] THEN [inTime]  ELSE '2011-06-16 00:00:00' END, CASE  WHEN isdate([outTime]) = 1 THEN   CASE    WHEN '2011-06-16 23:59:59' > [outTime] THEN [outTime]    ELSE '2011-06-16 23:59:59'   END  else   case    WHEN '2011-06-16 23:59:59' > [inTime] + 604800 THEN [inTime] + 604800    ELSE '2011-06-16 23:59:59'   END END)  AS v1 FROM [dbo].[Info] WHERE   [cName] LIKE 'T%' AND [b] <> 0 AND CONVERT(INT, [evt]) & 7 = 4 AND isdate([inTime]) = 1 AND  [inTime] <= '2011-06-16 23:59:59' AND  [outTime] >= '2011-06-16 00:00:00'), 
valDiff11 AS (SELECT datediff(second,CASE  WHEN '2011-06-17 00:00:00' < [inTime] THEN [inTime]  ELSE '2011-06-17 00:00:00' END, CASE  WHEN isdate([outTime]) = 1 THEN   CASE    WHEN '2011-06-17 23:59:59' > [outTime] THEN [outTime]    ELSE '2011-06-17 23:59:59'   END  else   case    WHEN '2011-06-17 23:59:59' > [inTime] + 604800 THEN [inTime] + 604800    ELSE '2011-06-17 23:59:59'   END END)  AS v1 FROM [dbo].[Info] WHERE   [cName] LIKE 'T%' AND [b] <> 0 AND CONVERT(INT, [evt]) & 7 = 4 AND isdate([inTime]) = 1 AND  [inTime] <= '2011-06-17 23:59:59' AND  [outTime] >= '2011-06-17 00:00:00'), 
valDiff12 AS (SELECT datediff(second,CASE  WHEN '2011-06-18 00:00:00' < [inTime] THEN [inTime]  ELSE '2011-06-18 00:00:00' END, CASE  WHEN isdate([outTime]) = 1 THEN   CASE    WHEN '2011-06-18 23:59:59' > [outTime] THEN [outTime]    ELSE '2011-06-18 23:59:59'   END  else   case    WHEN '2011-06-18 23:59:59' > [inTime] + 604800 THEN [inTime] + 604800    ELSE '2011-06-18 23:59:59'   END END)  AS v1 FROM [dbo].[Info] WHERE   [cName] LIKE 'T%' AND [b] <> 0 AND CONVERT(INT, [evt]) & 7 = 4 AND isdate([inTime]) = 1 AND  [inTime] <= '2011-06-18 23:59:59' AND  [outTime] >= '2011-06-18 00:00:00'), 
valDiff13 AS (SELECT datediff(second,CASE  WHEN '2011-06-19 00:00:00' < [inTime] THEN [inTime]  ELSE '2011-06-19 00:00:00' END, CASE  WHEN isdate([outTime]) = 1 THEN   CASE    WHEN '2011-06-19 23:59:59' > [outTime] THEN [outTime]    ELSE '2011-06-19 23:59:59'   END  else   case    WHEN '2011-06-19 23:59:59' > [inTime] + 604800 THEN [inTime] + 604800    ELSE '2011-06-19 23:59:59'   END END)  AS v1 FROM [dbo].[Info] WHERE   [cName] LIKE 'T%' AND [b] <> 0 AND CONVERT(INT, [evt]) & 7 = 4 AND isdate([inTime]) = 1 AND  [inTime] <= '2011-06-19 23:59:59' AND  [outTime] >= '2011-06-19 00:00:00'), 
valDiff14 AS (SELECT datediff(second,CASE  WHEN '2011-06-20 00:00:00' < [inTime] THEN [inTime]  ELSE '2011-06-20 00:00:00' END, CASE  WHEN isdate([outTime]) = 1 THEN   CASE    WHEN '2011-06-20 23:59:59' > [outTime] THEN [outTime]    ELSE '2011-06-20 23:59:59'   END  else   case    WHEN '2011-06-20 23:59:59' > [inTime] + 604800 THEN [inTime] + 604800    ELSE '2011-06-20 23:59:59'   END END)  AS v1 FROM [dbo].[Info] WHERE   [cName] LIKE 'T%' AND [b] <> 0 AND CONVERT(INT, [evt]) & 7 = 4 AND isdate([inTime]) = 1 AND  [inTime] <= '2011-06-20 23:59:59' AND  [outTime] >= '2011-06-20 00:00:00'), 
valDiff15 AS (SELECT datediff(second,CASE  WHEN '2011-06-21 00:00:00' < [inTime] THEN [inTime]  ELSE '2011-06-21 00:00:00' END, CASE  WHEN isdate([outTime]) = 1 THEN   CASE    WHEN '2011-06-21 23:59:59' > [outTime] THEN [outTime]    ELSE '2011-06-21 23:59:59'   END  else   case    WHEN '2011-06-21 23:59:59' > [inTime] + 604800 THEN [inTime] + 604800    ELSE '2011-06-21 23:59:59'   END END)  AS v1 FROM [dbo].[Info] WHERE   [cName] LIKE 'T%' AND [b] <> 0 AND CONVERT(INT, [evt]) & 7 = 4 AND isdate([inTime]) = 1 AND  [inTime] <= '2011-06-21 23:59:59' AND  [outTime] >= '2011-06-21 00:00:00'), 
valDiff16 AS (SELECT datediff(second,CASE  WHEN '2011-06-22 00:00:00' < [inTime] THEN [inTime]  ELSE '2011-06-22 00:00:00' END, CASE  WHEN isdate([outTime]) = 1 THEN   CASE    WHEN '2011-06-22 23:59:59' > [outTime] THEN [outTime]    ELSE '2011-06-22 23:59:59'   END  else   case    WHEN '2011-06-22 23:59:59' > [inTime] + 604800 THEN [inTime] + 604800    ELSE '2011-06-22 23:59:59'   END END)  AS v1 FROM [dbo].[Info] WHERE   [cName] LIKE 'T%' AND [b] <> 0 AND CONVERT(INT, [evt]) & 7 = 4 AND isdate([inTime]) = 1 AND  [inTime] <= '2011-06-22 23:59:59' AND  [outTime] >= '2011-06-22 00:00:00'), 
valDiff17 AS (SELECT datediff(second,CASE  WHEN '2011-06-23 00:00:00' < [inTime] THEN [inTime]  ELSE '2011-06-23 00:00:00' END, CASE  WHEN isdate([outTime]) = 1 THEN   CASE    WHEN '2011-06-23 23:59:59' > [outTime] THEN [outTime]    ELSE '2011-06-23 23:59:59'   END  else   case    WHEN '2011-06-23 23:59:59' > [inTime] + 604800 THEN [inTime] + 604800    ELSE '2011-06-23 23:59:59'   END END)  AS v1 FROM [dbo].[Info] WHERE   [cName] LIKE 'T%' AND [b] <> 0 AND CONVERT(INT, [evt]) & 7 = 4 AND isdate([inTime]) = 1 AND  [inTime] <= '2011-06-23 23:59:59' AND  [outTime] >= '2011-06-23 00:00:00'), 
valDiff18 AS (SELECT datediff(second,CASE  WHEN '2011-06-24 00:00:00' < [inTime] THEN [inTime]  ELSE '2011-06-24 00:00:00' END, CASE  WHEN isdate([outTime]) = 1 THEN   CASE    WHEN '2011-06-24 23:59:59' > [outTime] THEN [outTime]    ELSE '2011-06-24 23:59:59'   END  else   case    WHEN '2011-06-24 23:59:59' > [inTime] + 604800 THEN [inTime] + 604800    ELSE '2011-06-24 23:59:59'   END END)  AS v1 FROM [dbo].[Info] WHERE   [cName] LIKE 'T%' AND [b] <> 0 AND CONVERT(INT, [evt]) & 7 = 4 AND isdate([inTime]) = 1 AND  [inTime] <= '2011-06-24 23:59:59' AND  [outTime] >= '2011-06-24 00:00:00'), 
valDiff19 AS (SELECT datediff(second,CASE  WHEN '2011-06-25 00:00:00' < [inTime] THEN [inTime]  ELSE '2011-06-25 00:00:00' END, CASE  WHEN isdate([outTime]) = 1 THEN   CASE    WHEN '2011-06-25 23:59:59' > [outTime] THEN [outTime]    ELSE '2011-06-25 23:59:59'   END  else   case    WHEN '2011-06-25 23:59:59' > [inTime] + 604800 THEN [inTime] + 604800    ELSE '2011-06-25 23:59:59'   END END)  AS v1 FROM [dbo].[Info] WHERE   [cName] LIKE 'T%' AND [b] <> 0 AND CONVERT(INT, [evt]) & 7 = 4 AND isdate([inTime]) = 1 AND  [inTime] <= '2011-06-25 23:59:59' AND  [outTime] >= '2011-06-25 00:00:00'), 
valDiff20 AS (SELECT datediff(second,CASE  WHEN '2011-06-26 00:00:00' < [inTime] THEN [inTime]  ELSE '2011-06-26 00:00:00' END, CASE  WHEN isdate([outTime]) = 1 THEN   CASE    WHEN '2011-06-26 23:59:59' > [outTime] THEN [outTime]    ELSE '2011-06-26 23:59:59'   END  else   case    WHEN '2011-06-26 23:59:59' > [inTime] + 604800 THEN [inTime] + 604800    ELSE '2011-06-26 23:59:59'   END END)  AS v1 FROM [dbo].[Info] WHERE   [cName] LIKE 'T%' AND [b] <> 0 AND CONVERT(INT, [evt]) & 7 = 4 AND isdate([inTime]) = 1 AND  [inTime] <= '2011-06-26 23:59:59' AND  [outTime] >= '2011-06-26 00:00:00'), 
valDiff21 AS (SELECT datediff(second,CASE  WHEN '2011-06-27 00:00:00' < [inTime] THEN [inTime]  ELSE '2011-06-27 00:00:00' END, CASE  WHEN isdate([outTime]) = 1 THEN   CASE    WHEN '2011-06-27 23:59:59' > [outTime] THEN [outTime]    ELSE '2011-06-27 23:59:59'   END  else   case    WHEN '2011-06-27 23:59:59' > [inTime] + 604800 THEN [inTime] + 604800    ELSE '2011-06-27 23:59:59'   END END)  AS v1 FROM [dbo].[Info] WHERE   [cName] LIKE 'T%' AND [b] <> 0 AND CONVERT(INT, [evt]) & 7 = 4 AND isdate([inTime]) = 1 AND  [inTime] <= '2011-06-27 23:59:59' AND  [outTime] >= '2011-06-27 00:00:00'), 
valDiff22 AS (SELECT datediff(second,CASE  WHEN '2011-06-28 00:00:00' < [inTime] THEN [inTime]  ELSE '2011-06-28 00:00:00' END, CASE  WHEN isdate([outTime]) = 1 THEN   CASE    WHEN '2011-06-28 23:59:59' > [outTime] THEN [outTime]    ELSE '2011-06-28 23:59:59'   END  else   case    WHEN '2011-06-28 23:59:59' > [inTime] + 604800 THEN [inTime] + 604800    ELSE '2011-06-28 23:59:59'   END END)  AS v1 FROM [dbo].[Info] WHERE   [cName] LIKE 'T%' AND [b] <> 0 AND CONVERT(INT, [evt]) & 7 = 4 AND isdate([inTime]) = 1 AND  [inTime] <= '2011-06-28 23:59:59' AND  [outTime] >= '2011-06-28 00:00:00'), 
valDiff23 AS (SELECT datediff(second,CASE  WHEN '2011-06-29 00:00:00' < [inTime] THEN [inTime]  ELSE '2011-06-29 00:00:00' END, CASE  WHEN isdate([outTime]) = 1 THEN   CASE    WHEN '2011-06-29 23:59:59' > [outTime] THEN [outTime]    ELSE '2011-06-29 23:59:59'   END  else   case    WHEN '2011-06-29 23:59:59' > [inTime] + 604800 THEN [inTime] + 604800    ELSE '2011-06-29 23:59:59'   END END)  AS v1 FROM [dbo].[Info] WHERE   [cName] LIKE 'T%' AND [b] <> 0 AND CONVERT(INT, [evt]) & 7 = 4 AND isdate([inTime]) = 1 AND  [inTime] <= '2011-06-29 23:59:59' AND  [outTime] >= '2011-06-29 00:00:00'), 
valDiff24 AS (SELECT datediff(second,CASE  WHEN '2011-06-30 00:00:00' < [inTime] THEN [inTime]  ELSE '2011-06-30 00:00:00' END, CASE  WHEN isdate([outTime]) = 1 THEN   CASE    WHEN '2011-06-30 23:59:59' > [outTime] THEN [outTime]    ELSE '2011-06-30 23:59:59'   END  else   case    WHEN '2011-06-30 23:59:59' > [inTime] + 604800 THEN [inTime] + 604800    ELSE '2011-06-30 23:59:59'   END END)  AS v1 FROM [dbo].[Info] WHERE   [cName] LIKE 'T%' AND [b] <> 0 AND CONVERT(INT, [evt]) & 7 = 4 AND isdate([inTime]) = 1 AND  [inTime] <= '2011-06-30 23:59:59' AND  [outTime] >= '2011-06-30 00:00:00') 
SELECT SUM(CASE WHEN v1 < 604800 THEN v1 ELSE 604800 END) FROM valDiff0
 UNION ALL
 SELECT SUM(CASE WHEN v1 < 604800 THEN v1 ELSE 604800 END) FROM valDiff1
 UNION ALL
 SELECT SUM(CASE WHEN v1 < 604800 THEN v1 ELSE 604800 END) FROM valDiff2
 UNION ALL
 SELECT SUM(CASE WHEN v1 < 604800 THEN v1 ELSE 604800 END) FROM valDiff3
 UNION ALL
 SELECT SUM(CASE WHEN v1 < 604800 THEN v1 ELSE 604800 END) FROM valDiff4
 UNION ALL
 SELECT SUM(CASE WHEN v1 < 604800 THEN v1 ELSE 604800 END) FROM valDiff5
 UNION ALL
 SELECT SUM(CASE WHEN v1 < 604800 THEN v1 ELSE 604800 END) FROM valDiff6
 UNION ALL
 SELECT SUM(CASE WHEN v1 < 604800 THEN v1 ELSE 604800 END) FROM valDiff7
 UNION ALL
 SELECT SUM(CASE WHEN v1 < 604800 THEN v1 ELSE 604800 END) FROM valDiff8
 UNION ALL
 SELECT SUM(CASE WHEN v1 < 604800 THEN v1 ELSE 604800 END) FROM valDiff9
 UNION ALL
 SELECT SUM(CASE WHEN v1 < 604800 THEN v1 ELSE 604800 END) FROM valDiff10
 UNION ALL
 SELECT SUM(CASE WHEN v1 < 604800 THEN v1 ELSE 604800 END) FROM valDiff11
 UNION ALL
 SELECT SUM(CASE WHEN v1 < 604800 THEN v1 ELSE 604800 END) FROM valDiff12
 UNION ALL
 SELECT SUM(CASE WHEN v1 < 604800 THEN v1 ELSE 604800 END) FROM valDiff13
 UNION ALL
 SELECT SUM(CASE WHEN v1 < 604800 THEN v1 ELSE 604800 END) FROM valDiff14
 UNION ALL
 SELECT SUM(CASE WHEN v1 < 604800 THEN v1 ELSE 604800 END) FROM valDiff15
 UNION ALL
 SELECT SUM(CASE WHEN v1 < 604800 THEN v1 ELSE 604800 END) FROM valDiff16
 UNION ALL
 SELECT SUM(CASE WHEN v1 < 604800 THEN v1 ELSE 604800 END) FROM valDiff17
 UNION ALL
 SELECT SUM(CASE WHEN v1 < 604800 THEN v1 ELSE 604800 END) FROM valDiff18
 UNION ALL
 SELECT SUM(CASE WHEN v1 < 604800 THEN v1 ELSE 604800 END) FROM valDiff19
 UNION ALL
 SELECT SUM(CASE WHEN v1 < 604800 THEN v1 ELSE 604800 END) FROM valDiff20
 UNION ALL
 SELECT SUM(CASE WHEN v1 < 604800 THEN v1 ELSE 604800 END) FROM valDiff21
 UNION ALL
 SELECT SUM(CASE WHEN v1 < 604800 THEN v1 ELSE 604800 END) FROM valDiff22
 UNION ALL
 SELECT SUM(CASE WHEN v1 < 604800 THEN v1 ELSE 604800 END) FROM valDiff23
 UNION ALL
 SELECT SUM(CASE WHEN v1 < 604800 THEN v1 ELSE 604800 END) FROM valDiff24

Как можно оптимизировать что-то подобное?

1 Ответ

2 голосов
/ 14 июля 2011

Во-первых, я бы попытался немного сократить его, создав таблицу календаря. Это также может частично улучшить производительность ...

WITH
  Calendar AS
(
  SELECT 0 AS [id], CAST('2011 Jun 06' AS DATETIME) AS [DateStart], CAST('2011 Jun 06' AS DATETIME) + 1 AS [DateEnd]
  UNION ALL
  SELECT id + 1, [DateStart] + 1, [DateStart] + 2 FROM Calendar WHERE id < 24
)
,
  FilteredData AS
(
  SELECT
    COALESCE(Info.[inTime],  CAST('2011 Jun 06')) AS [inTime],
    COALESCE(Info.[outTime], Info.[inTime] + 7)   AS [outTime]
  FROM
    [dbo].[Info]
  WHERE
         Info.[cName] LIKE 'T%'
     AND Info.[b] <> 0
     AND CONVERT(INT, Info.[evt]) & 7 = 4
     AND (Info.[outTime] IS NULL OR Info.[outTime] >= CAST('2011 Jun 06' AS DATETIME)
     AND (Info.[inTime]  IS NULL OR Info.[inTime]  <  CAST('2011 Jun 06' AS DATETIME) + 25)
)
,
  CleanedData AS
(
  SELECT
    [Calendar].id,
    CASE  
      WHEN Calendar.[DateStart] < Info.[inTime]  THEN Info.[inTime]  
      ELSE Calendar.[DateStart] 
    END AS [inTime], 
    CASE    
      WHEN Calendar.[DateEnd]   > Info.[outTime] THEN Info.[outTime]
      ELSE Calendar.[DateEnd]   
    END AS [outTime]
 FROM
    [Calendar]
  INNER JOIN
    [FilteredData] AS [Info]
      ON  Info.[inTime]  <  Calendar.[DateEnd]
      AND Info.[outTime] >= Calendar.[DateStart]
)

SELECT
  [id],
  SUM(DATEDIFF(SECOND, [InTime], [OutTime])) AS duration
FROM
  [CleanedData]
GROUP BY
  [id]

-- Note: The CleanedData step causes the InTime and OutTime to be no more than a day appart.
-- This means that there is no need to check the DATEDIFF is less than 1 week long.


С точки зрения оптимизации, какие индексы у вас есть на столе? Они могут, конечно, помочь здесь ...

  WHERE
     Info.[cName] LIKE 'T%'
     AND Info.[b] <> 0

Наконец, индекс не может помочь с CONVERT(INT, Info.[evt]) & 7 = 4. Можете ли вы добавить вычисляемое поле в таблицу, которую можно проиндексировать? Или измените одно поле на несколько полей; набор флагов для разных режимов / состояний? (Или составить производную таблицу с этой информацией?) Или индексация этого поля не будет иметь для вас большого значения?

У вас есть логика, которая гласит: «Если outTime IS NULL, используйте inTime плюс 1 неделя». Что вы хотите сделать, если inTime и OutTime равны NULL?

Существует также проблема, касающаяся оптимизации фильтрации данных по интересующим вас датам. Если событие может иметь любую продолжительность, вы должны проверить оба the in и out раз, что убивает вашу способность использовать индекс. Если вы знаете, что событие имеет максимальную длину, вы можете сделать что-то вроде этого ...

WHERE
      Info.inTime  > (myEarliestDate) - (myLongestDuration)
  AND Info.inTime  < (myLatestDate)
  AND Into.OutTime > (myEarliestDate)

То, что это дает вам, это > И <, обернутое вокруг вашего поля inTime, явно ограничивающее все до очень определенного диапазона данных. Поэтому я бы добавил это в конец предложения WHERE под названием FilteredData. (При условии, что ни одно событие не длится более 7 дней.)

     AND (Info.[inTime]  IS NULL OR Info.[inTime]  >= CAST('2011 Jun 06' AS DATETIME) - 7)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...