视图中的子查询运行缓慢

时间:2013-04-12 09:24:09

标签: sql sql-server performance view subquery

您好我的观点有问题。子查询导致视图运行非常缓慢。

SELECT dbo.Calls.CallID
      ,dbo.Calls.StartTime
      ,dbo.Calls.EndTime
      ,dbo.Connections.Connectionname
      ,dbo.Repositorys.RepositoryName
      ,REPLACE(dbo.Calls.Querytime ,',' ,'.') AS Querytijd
      ,dbo.Calls.Uur
      ,dbo.Calls.DayOfMonth
      ,REPLACE(
           (
               SELECT MAX(Querytime)  AS MaxQueryTime
               FROM   dbo.Calls       AS C
               WHERE  (
                          DATEPART(yyyy ,StartTime)=DATEPART(yyyy ,dbo.Calls.StartTime)
                      )
                      AND (DATEPART(M ,StartTime)=DATEPART(M,dbo.Calls.StartTime))               
                      AND (DayOfMonth=dbo.Calls.DayOfMonth)
                      AND (Uur=dbo.Calls.Uur)
                      AND (
                              DATEPART(MINUTE ,dbo.Calls.StartTime)=DATEPART(Minute ,StartTime)
                          )
           )
          ,','
          ,'.'
       ) AS MaxQueryTime
FROM   dbo.Calls
       INNER JOIN dbo.Connections
            ON  dbo.Calls.ConnectionID = dbo.Connections.ConnectionID
       LEFT OUTER JOIN dbo.Repositorys
            ON  dbo.Connections.RepositoryID = dbo.Repositorys.RepositoryID

我基本上想要最大的QueryTime,其中StartTime的年/月/日/小时/分钟是相同的。

4 个答案:

答案 0 :(得分:2)

在SQLServer2005 +中,您可以使用OVER()子句

SELECT dbo.Calls.CallID, 
       dbo.Calls.StartTime, 
       dbo.Calls.EndTime,
       dbo.Connections.Connectionname,
       dbo.Repositorys.RepositoryName, 
       REPLACE(dbo.Calls.Querytime, ',', '.') AS Querytijd, 
       dbo.Calls.Uur, 
       dbo.Calls.DayOfMonth, 
       REPLACE(MAX(Querytime) OVER(PARTITION BY DATEPART(yyyy ,StartTime), 
                                                DATEPART(Minute ,StartTime), 
                                                DayOfMonth, Uur), ',', '.'
               ) AS MaxQueryTime
FROM dbo.Calls INNER JOIN dbo.Connections 
                 ON dbo.Calls.ConnectionID = dbo.Connections.ConnectionID 
               LEFT OUTER JOIN dbo.Repositorys 
                 ON dbo.Connections.RepositoryID = dbo.Repositorys.RepositoryID

答案 1 :(得分:0)

查询是否有效?

当我查看您的Query“From”关键字在单个Query中使用两次。 只有两个表的连接。如果你想快速得到你的结果,那么首先过滤两个表然后进行连接,这样连接中的行数就会减少,这将优化你的结果。

SELECT dbo.Calls.CallID, dbo.Calls.StartTime, dbo.Calls.EndTime, 
dbo.Connections.Connectionname, dbo.Repositorys.RepositoryName, 
REPLACE(dbo.Calls.Querytime, ',', '.') AS Querytijd, dbo.Calls.Uur, 
dbo.Calls.DayOfMonth, REPLACE((SELECT MAX(Querytime) AS MaxQueryTime 
FROM dbo.Calls AS C 
WHERE (DATEPART(yyyy, StartTime) = DATEPART(yyyy, dbo.Calls.StartTime))
 AND (DayOfMonth = dbo.Calls.DayOfMonth) AND (Uur = dbo.Calls.Uur) AND 
 (DATEPART(MINUTE, dbo.Calls.StartTime) = DATEPART(Minute, StartTime))), ',', '.') AS MaxQueryTime 

 FROM dbo.Calls INNER JOIN dbo.Connections ON dbo.Calls.ConnectionID = dbo.Connections.ConnectionID 
 LEFT OUTER JOIN dbo.Repositorys ON dbo.Connections.RepositoryID = dbo.Repositorys.RepositoryID

答案 2 :(得分:0)

SELECT dbo.Calls.CallID
  ,dbo.Calls.StartTime
  ,dbo.Calls.EndTime
  ,dbo.Connections.Connectionname
  ,dbo.Repositorys.RepositoryName
  ,REPLACE(dbo.Calls.Querytime ,',' ,'.') AS Querytijd
  ,dbo.Calls.Uur
  ,dbo.Calls.DayOfMonth
  ,REPLACE( QUERYTIME,',','.') AS MaxQueryTime
FROM   dbo.Calls
   INNER JOIN dbo.Connections
        ON  dbo.Calls.ConnectionID = dbo.Connections.ConnectionID
   LEFT OUTER JOIN dbo.Repositorys
        ON  dbo.Connections.RepositoryID = dbo.Repositorys.RepositoryID
LEFT JOIN 
(
SELECT StartTime, Uur, DayOfMonth, StartTime, MAX(QUERYTIME) AS QUERYTIME
FROM dbo.Calls       
GROUP BY StartTime, Uur, DayOfMonth, StartTime
) AS C
ON DATEPART(yyyy ,C.StartTime)=DATEPART(yyyy ,dbo.Calls.StartTime)
AND C.DayOfMonth=dbo.Calls.DayOfMonth
AND C.Uur=dbo.Calls.Uur
AND DATEPART(MINUTE ,dbo.Calls.StartTime)=DATEPART(Minute ,C.StartTime)

答案 3 :(得分:0)

当我查看您的查询时...您正在计算每行的“MaxQueryTime”。要优化此查询,您可以使用可以组合到结果集的联合关键字计算“MaxQueryTime”。根据我的说法,“MaxQueryTime”对所有人来说都是一样的。

(SELECT REPLACE(MAX(Querytime),',','.')  AS MaxQueryTime
               FROM   dbo.Calls       AS C
               WHERE  (
                          DATEPART(yyyy ,StartTime)=DATEPART(yyyy ,dbo.Calls.StartTime)
                      )
                      AND (DayOfMonth=dbo.Calls.DayOfMonth)
                      AND (Uur=dbo.Calls.Uur)
                      AND (
                              DATEPART(MINUTE ,dbo.Calls.StartTime)=DATEPART(Minute ,StartTime)
                          )) union all

                ( SELECT dbo.Calls.CallID
      ,dbo.Calls.StartTime
      ,dbo.Calls.EndTime
      ,dbo.Connections.Connectionname
      ,dbo.Repositorys.RepositoryName
      ,REPLACE(dbo.Calls.Querytime ,',' ,'.') AS Querytijd
      ,dbo.Calls.Uur
      ,dbo.Calls.DayOfMonth

FROM   dbo.Calls
       INNER JOIN dbo.Connections
            ON  dbo.Calls.ConnectionID = dbo.Connections.ConnectionID
       LEFT OUTER JOIN dbo.Repositorys
            ON  dbo.Connections.RepositoryID = dbo.Repositorys.RepositoryID         )