2013-01-19 113 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, 

我想你要走的想法
你应该阅读有关窗函数及以上()子句

如果你想要整个查询发布一些示例数据和表架构