2013-01-19 112 views
1

全部,SQL Server 2008排序很慢

我有一個大約250000條記錄的用戶表。我有以下查詢(請注意,我是SQL的新手),但執行時間非常長。我檢查了執行計劃,執行時間的60%正在被2種類型佔用。

SELECT TOP 50 
    Flows_Users.UserName, 
    Flows_Users.UserID, 
    Flows_Users.ImageName, 
    Flows_Users.DisplayName, 
    Flows_UserBios.bio, 
    FlowsCount = (
     SELECT Count(1) 
     FROM Flows_Flows 
     WHERE UserID = Flows_Users.UserID 
      AND Flows_Flows.Active = '1' 
    ), 
    BeatsCount = (
     SELECT Count(1) 
     FROM Flows_Beats 
     WHERE UserName_ID = Flows_Users.UserID 
      AND Flows_Beats.Active = '1' 
    ), 
    FollowersCount = (
     SELECT Count(1) 
     FROM Flows_Follow 
     WHERE FOLLOWING = Flows_Users.UserID 
    ), 
    FollowingCount = (
     SELECT Count(1) 
     FROM Flows_Follow 
     WHERE FOLLOWER = Flows_Users.UserID 
    ), 
    ISNULL(SUM(Flows_Flows_Likes_Dislikes.[Like]), 0) AS Likes, 
    ISNULL(SUM(Flows_Flows_Likes_Dislikes.Dislike), 0) AS DisLikes 
FROM Flows_Users 
LEFT JOIN Flows_Flows 
    ON Flows_Users.UserID = Flows_Flows.UserID 
LEFT JOIN Flows_UserBios 
    ON Flows_Users.UserID = Flows_UserBios.userid 
LEFT JOIN Flows_Flows_Likes_Dislikes 
    ON Flows_Flows.FlowID = Flows_Flows_Likes_Dislikes.FlowID 
WHERE Flows_Users.UserID = Flows_Users.UserID 
GROUP BY Flows_Users.UserID, 
    Flows_Users.UserName, 
    Flows_Users.ImagePath, 
    Flows_Users.ImageName, 
    Flows_Users.DisplayName, 
    Flows_UserBios.bio 
ORDER BY 
    [Likes] DESC, 
    [Dislikes] ASC, 
    FlowsCount DESC 

我知道這是一團糟,但它只有在成千上萬的表中才能完成工作。有什麼辦法可以讓這個更快嗎?現在需要5-10分鐘才能執行。這也是在存儲過程中,我覺得我有需要索引,索引的列。

+1

我的建議。 1.用連接或窗口操作替換子查詢,然後2.查看索引。 1.應該幫助你將查詢減少到可管理的位,並且2將有助於加快速度。 –

+0

你能告訴我們**這些表上有哪些索引**? –

回答

0

嘗試這種改變,因爲我沒有這些表,你可能需要修補它。驗證後,檢查執行計劃並查找表掃描。然後添加索引。如果數字索引很大,請考慮包含的列。我個人會修改這個視圖,而不是存儲過程,但多數民衆贊成在我的偏好。

有人曾告訴我,計數*實際上稍微好一點,但是這是在SQL Server 2000日,不確定是否仍然相關。

如果可能,請修改左連接到內連接。 IE瀏覽器。我假設用戶不會被硬刪除,所以會修改用戶ID連接到內部和過濾器被禁用的帳戶。

SELECT TOP 50 
    Flows_Users.UserName, 
    Flows_Users.UserID, 
    Flows_Users.ImageName, 
    Flows_Users.DisplayName, 
    Flows_UserBios.bio, 
    a.FlowsCount, 
    b.BeatsCount, 
    c.FollowersCount, 
    d.FollowingCount, 
    ISNULL(SUM(Flows_Flows_Likes_Dislikes.[Like]), 0) AS Likes, 
    ISNULL(SUM(Flows_Flows_Likes_Dislikes.Dislike), 0) AS DisLikes 
FROM Flows_Users 
LEFT JOIN  ( SELECT Count(*) FlowCount 
     FROM Flows_Flows 
     WHERE UserID = Flows_Users.UserID 
      AND Flows_Flows.Active = '1') a 
LEFT JOIN (SELECT Count(*) as 
     FROM Flows_Beats 
     WHERE UserName_ID = Flows_Users.UserID 
      AND Flows_Beats.Active = '1') b 
LEFT JOIN (SELECT Count(*) as FollowersCount 
     FROM Flows_Follow 
     WHERE FOLLOWING = Flows_Users.UserID) c 
LEFT JOIN (
     SELECT Count(*) as FollowingCount 
     FROM Flows_Follow 
     WHERE FOLLOWER = Flows_Users.UserID) d 
LEFT JOIN Flows_Flows 
    ON Flows_Users.UserID = Flows_Flows.UserID 
LEFT JOIN Flows_UserBios 
    ON Flows_Users.UserID = Flows_UserBios.userid 
LEFT JOIN Flows_Flows_Likes_Dislikes 
    ON Flows_Flows.FlowID = Flows_Flows_Likes_Dislikes.FlowID 
WHERE Flows_Users.UserID = Flows_Users.UserID 
GROUP BY Flows_Users.UserID, 
    Flows_Users.UserName, 
    Flows_Users.ImagePath, 
    Flows_Users.ImageName, 
    Flows_Users.DisplayName, 
    Flows_UserBios.bio 
ORDER BY 
    [Likes] DESC, 
    [Dislikes] ASC, 
    FlowsCount DESC 
+0

在提出所有建議之後,它將左連接更改爲內連接,從而加速了一切。相同的數據現在在一秒鐘內返回。瘋!謝謝大家! – nawlrus

0

當您執行其他建議時,將查詢轉換爲存儲過程。這樣,每次查詢運行時,服務器都不必創建執行計劃。

+0

所有查詢計劃都在一定程度上被緩存。 –

1

爲@PreetSanght sugested 變化

這部分

FlowsCount = (
    SELECT Count(1) 
    FROM Flows_Flows 
    WHERE UserID = Flows_Users.UserID 
     AND Flows_Flows.Active = '1' 
), 
BeatsCount = (
    SELECT Count(1) 
    FROM Flows_Beats 
    WHERE UserName_ID = Flows_Users.UserID 
     AND Flows_Beats.Active = '1' 
), 
FollowersCount = (
    SELECT Count(1) 
    FROM Flows_Follow 
    WHERE FOLLOWING = Flows_Users.UserID 
), 
FollowingCount = (
    SELECT Count(1) 
    FROM Flows_Follow 
    WHERE FOLLOWER = Flows_Users.UserID 
), 

弄成這個樣子

sum(case when Flows_Flows.Active = '1' then 1 else 0 end) 
over (partition by UserID order by Flows_Flows.UserID) as FlowsCount, 

sum(case when Flows_Beats.Active = '1' then 1 else 0 end) 
over (partition by UserName_ID order by Flows_Flows.UserID) as BeatsCount, 

count(1) over(parition by FOLLOWING order by Flows_Flows.UserID) as FollowersCount, 
count(1) over(parition by FOLLOWER order by Flows_Flows.UserID) as FollowingCount, 

我想你要走的想法
你應該閱讀有關窗函數及以上()子句

如果你想要整個查詢發佈一些示例數據和表架構