希望优化此SQL Server语句的性能

时间:2011-07-14 07:32:14

标签: sql sql-server performance select

我知道要求在这个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 个答案:

答案 0 :(得分:2)

首先,我会尝试通过创建一个Calendar表来缩短它。这也可以部分改善绩效......

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为NULL,则使用inTime加1周”。如果inTime和OutTime都为NULL,你想做什么?

根据您感兴趣的日期,还有一个关于过滤数据的优化问题。如果某个事件任何持续时间,您必须检查两者 inout次,会影响您使用索引的能力。但是,如果您知道某个事件的最大长度,则可以执行以下操作...

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

给你的是><包围你的inTime字段,明确地将所有内容限制在非常特定的数据范围内。因此,我将其添加到名为FilteredData的WHERE子句的末尾。 (假设任何事件都不会超过7天。)

     AND (Info.[inTime]  IS NULL OR Info.[inTime]  >= CAST('2011 Jun 06' AS DATETIME) - 7)