Sql 视图中的子查询运行缓慢

Sql 视图中的子查询运行缓慢,sql,sql-server,performance,view,subquery,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.Cal

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

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
基本上,我希望在起始时间的年/月/日/小时/分钟相同的情况下获得最大查询时间。

查询是否有效

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

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

当我看到你的询问。。您正在为每一行计算“MaxQueryTime”。要优化此查询,您可以计算一次“MaxQueryTime”,然后使用union关键字将其组合到结果集中。根据我的说法,“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         )

在SQLServer2005+中,可以使用子句


来自的第一个
是子选择的一部分-我刚刚重新格式化了查询;现在可能更清楚了。我基本上是在起始时间相同的地方编辑的,直到秒。所以年/月/月/日/小时/分钟
(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         )
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