2016-04-01 35 views
1

私は条件付きcount()ステートメントを使用して最適化できると信じている本当に遅いSQLステートメントがありますが、これを行う方法を考えることはできません。複数のテーブルから数えて効率的な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

あなたは 'COUNT'を実行しているテーブルでUserIDをインデックスに登録していますか?それがあなたの問題でしょうか? UserID以外でカウントしている他のテーブル間に関連がない場合は、 'WHERE'節に既にあるもの以外のもの、つまりUserIDを適用できる' COUNT'の条件はありません。 – strickt01

答えて

0

"explain"を使用して、クエリの実行方法を調べます。

インデックスを使用していない場合は、テーブルのインデックスを作成します。原則として、WHERE句に含まれる任意のフィールドにインデックスを設定します。

0

クエリプランがないとボトルネックがどこにあるのかを正確に把握することは難しいです。最も可能性のある問題は、COUNTを実行しているテーブルにUserIDのインデックスがないことです。この場合、クエリによって、各ユーザーの各テーブルで完全なテーブルスキャンが実行されます。したがって、次のクエリは、各テーブルに対して1回のテーブルスキャンを実行するので、このような事態を回避するのに役立ちます(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 

:それから考えるいずれか、またはすべてのテーブルのUserIdにインデックスがない場合

1) 1つを追加します。

2)UserIDためAudit_Trailにインデックスがある場合、あなたは、キーのルックアップを避けるために含ま列としてEntryTypeを追加する必要があります。これを評価するためにクエリプランを調べる必要があります。

関連する問題