2016-04-01 29 views
1

我有一个非常慢的SQL语句,我相信我可以使用条件count()语句进行优化,但我无法解决如何执行此操作。更高效的SQL从多个表中计数

SELECT TOP 10 U.UserID, 
       U.Fullname, 
       U.URL, 
       U.Fname, 
       U.ProfilePic, 

    (SELECT Count(ResourceID) 
    FROM resources R 
    WHERE R.UserID = U.UserID) AS ResourcesPosted, 

    (SELECT Count(JobID) 
    FROM Jobs J 
    WHERE J.UserID = U.UserID) AS JobsPosted, 

    (SELECT Count(AuditID) 
    FROM Audit_Trail AT 
    WHERE AT.UserID = U.UserID 
    AND TYPE = 1 
    AND Entry LIKE '%logged in%') AS TotalLogins, 

    (SELECT Count(EventID) 
    FROM Future_Events_Listing E 
    WHERE E.UserID = U.UserID) AS EventsPosted 
FROM User_basics U 
LEFT JOIN Pod_Membership PM ON PM.userID = U.UserID 
WHERE PodID = 268 

我可以做一些内部连接,然后有条件地计数项目?

+0

Pod_Membership表中的“PodID”?如果是这样的话,'LEFT JOIN'应该是'INNER JOIN',因为WHERE将它变成这样。 – strickt01

+0

@ strickt01谢谢,我现在已经这么做了。 – chris

+0

UserID是否在您正在执行COUNT表的表上编制索引 - 这是您的可能问题?如果除了UserID之外的其他表之间没有关联,那么除了'WHERE'子句中已经存在的'COUNT'外,没有关于'COUNT'的任何条件 - 即UserID。 – strickt01

回答

0

使用“解释”来了解如何执行查询。

如果它不使用索引,请索引您的表。作为一般规则,将索引放在WHERE子句中包含的任何字段中。

0

如果没有查询计划,很难确切地看到瓶颈的位置。最可能的问题是您正在执行COUNT的表中没有UserID索引。如果是这种情况,那么您的查询将导致每个用户在每张桌上进行全表扫描。所以下面的查询可能有助于避免这种可能性,因为它只会对每个表执行一次表扫描(尽管索引UserID是最好的解决方案,因为这应该只会导致每个表上的索引查找 - 您可能会考虑Audit_trail的可能例外需要包括TypeEntry您的索引,以避免潜在的非常昂贵的键查找):

SELECT TOP 10 U.UserID, 
      U.Fullname, 
      U.URL, 
      U.Fname, 
      U.ProfilePic, 
      ResourcesPosted, 
      JobsPosted, 
      TotalLogins, 
      EventsPosted 

FROM User_basics U 

INNER JOIN Pod_Membership PM ON PM.userID = U.UserID 
AND PodID = 268 

LEFT OUTER JOIN 
    (SELECT R.UserID, Count(ResourceID) AS ResourcesPosted 
    FROM resources R 
    GROUP BY R.UserID) res 
    ON res.UserID = U.UserID 

LEFT OUTER JOIN 
(SELECT J.UserID, Count(JobID) AS JobsPosted 
FROM Jobs J 
GROUP BY J.UserID) job 
ON job.UserID = U.UserID 

LEFT OUTER JOIN 
    (SELECT AT.UserID, Count(AuditID) AS TotalLogins 
    FROM Audit_Trail AT 
WHERE TYPE = 1 
AND Entry LIKE '%logged in%' 
GROUP BY AT.UserID) aud 
ON aud.UserID = U.UserID 

LEFT OUTER JOIN 
    (SELECT E.UserID, Count(EventID) AS EventsPosted 
    FROM Future_Events_Listing E 
    GROUP BY E.UserID) fut 
    ON fut.UserID = U.UserID 

所以:

1)如果在任一或所有表上UserId没有索引然后再考虑加一个。

2)如果在Audit_TrailUserID,那么你可能需要添加EntryType为包括列,以避免键查找索引。您将需要检查查询计划以评估此问题。