Sql server 优化此查询。与DBA在社交网络/社区类型网站上的工作相关

Sql server 优化此查询。与DBA在社交网络/社区类型网站上的工作相关,sql-server,tsql,Sql Server,Tsql,我想这是社交网络和社区类型网站中非常常见的SP。 我有一个SP,它返回用户“好友”页面上的所有好友,按当前在线的好友顺序,然后按字母顺序返回。它需要相当长的一段时间来加载,我期待着加快它 我记得在某个地方读到过这样的文章,将多个连接分解成更小的结果集可能会加快速度。我还没有尝试过这个方法,但我很想知道在这个过程中还有什么其他的建议 DECLARE @userID INT -- This variable is parsed in DECLARE @lastActivityMinutes INT

我想这是社交网络和社区类型网站中非常常见的SP。 我有一个SP,它返回用户“好友”页面上的所有好友,按当前在线的好友顺序,然后按字母顺序返回。它需要相当长的一段时间来加载,我期待着加快它

我记得在某个地方读到过这样的文章,将多个连接分解成更小的结果集可能会加快速度。我还没有尝试过这个方法,但我很想知道在这个过程中还有什么其他的建议

DECLARE @userID INT -- This variable is parsed in
DECLARE @lastActivityMinutes INT

SET @lastActivitytMinutes = '15'

SELECT 
    Active = CASE WHEN DATEDIFF("n", b.LastActivityDate ,GETDATE()) < @lastActivityMinutes THEN 1 ELSE 0 END, 
    a.DisplayName, a.ImageFile, a.UserId, b.LastActivityDate
FROM 
    Profile AS a 
        INNER JOIN aspnet_Users as b on b.userId = a.UserId  
        LEFT JOIN Friend AS x ON x.UserID = a.UserID
        LEFT JOIN Friend AS z ON z.FriendID = a.UserID
WHERE   ((x.FriendId = @userID AND x.status = 1) -- Status = 1 means friendship accepted
        OR (z.UserID = @userID AND z.Status = 1))
GROUP BY a.userID, a.DisplayName, a.ImageFile, a.UserId, b.LastActivityDate
ORDER BY Active DESC, DisplayName ASC
我不知道如何在我的执行计划剪辑,但主要的瓶颈似乎是发生在合并连接右外连接,这是我的成本29%。在不同的阶段,并行性的成本也分别为9%、6%、5%和9%,总计为29%

我最初的想法是首先使用CTE从Profile表和aspnet表返回连接结果,然后对Friends表执行左连接。

您使用左连接两次连接Friend,然后使用WHERE条件删除左连接返回的NULL,然后使用GROUP by删除distincts

这不是最好的查询

你为什么不用这个:

SELECT  Active = CASE WHEN DATEDIFF("n", b.LastActivityDate ,GETDATE()) < @lastActivityMinutes THEN 1 ELSE 0 END,
        a.DisplayName, a.ImageFile, a.UserId, b.LastActivityDate
FROM    (
        SELECT  FriendID
        FROM    Friends
        WHERE   UserID = @UserId
                AND status = 1
        UNION
        SELECT  UserID
        FROM    Friends
        WHERE   FriendID = @UserId
                AND status = 1
        ) x
INNER JOIN
        Profile AS a 
ON      a.UserID = x.FriendID
INNER JOIN
        aspnet_Users as b
ON      b.userId = a.UserId
ORDER BY
        Active DESC, DisplayName ASC

是的,这就引出了我的第一个问题。有时,用户只发出或接收一个好友请求。这意味着ID可以存在于Friend表的UserID或FriendID列中。像你说的那样做内心的联结不会回报她的友谊。使用您的脚本,我的返回选择从395行变为362行。@Nai:是针对使用UNION ALL的新查询吗?这是针对旧查询的。对于这个,它不会返回任何行。我目前正在努力确定why@Nai对不起,是我的错。只要把外罩拆下就行了。查看更新。是的,我也删除了它。我想你可能已经把它钉在这里了,因为现在大部分工作都在索引扫描上,这是我的缺点,可以通过适当的索引进行优化。