优化查询以提高性能

时间:2014-10-14 17:52:34

标签: sql sql-server

如何优化以下SQL查询?我有这个查询,但我需要优化它,或者你有一个在线SQL重构工具的建议?

表:Membership

+---------+--------+
| GroupID | UserID |
+---------+--------+
|     123 |    605 |
|     124 |    605 |
|     125 |    605 |
|     123 |    606 |
|     125 |    606 |
|     124 |    607 |
+---------+--------+

表:content_group_membership

+---------+-----------+
| GroupID | ContentId |
+---------+-----------+
|   11111 |       123 |
|   22222 |       123 |
|   44444 |       124 |
|   22222 |       125 |
|   11111 |       126 |
|   33333 |       126 |
|   11111 |       125 |
+---------+-----------+

Membership表包含用户所属的groupID列表,content_group_membership表包含相应ContentID的允许groupID列表。

我们需要获取针对该用户限制的contentID列表,groupID的{​​{1}}应从UserID表和Membership获取} contentID以外的groupID groupIDContentID进行限制UserID

下面是查询,现在我们正在使用,当下面的查询用作子查询时,这会消耗三倍于获取结果所消耗的时间。因此,我们希望优化查询能够快速获取结果。

预期结果:33333

查询:

SELECT DISTINCT 
   [ContentID], groupid
FROM   
   [content_group_membership]
WHERE  
   contentid NOT IN (SELECT [ContentID]
                     FROM [content_group_membership]
                     WHERE GroupID IN (SELECT groupid
                                       FROM Membership
                                       WHERE UserID = 605 ))
   AND GroupID IN (SELECT GroupID
                   FROM [content_group_membership]
                   WHERE groupid NOT IN (SELECT groupid
                                         FROM Membership
                                         WHERE UserID = 605)) 

2 个答案:

答案 0 :(得分:0)

这应该是等效的,并且运行效率更高:

 SELECT DISTINCT [ContentID],
                groupid
FROM   [content_group_membership]
WHERE  contentid != ANY (SELECT [ContentID]
                         FROM   [content_group_membership]
                         WHERE  GroupID IN (SELECT groupid
                                            FROM   Membership
                                            WHERE  UserID = 605
                                                   AND Active = 1))
   AND GroupID NOT IN (SELECT groupid
                       FROM   Membership
                       WHERE  UserID = 605
                       AND Active = 1)) 

但是,对这种复杂性的查询可能会更好地作为一个过程。

答案 1 :(得分:0)

我没有足够的评论来评论,所以,它会这样做作为答案。

我相信这个查询是为CTE准备的,所以它不必执行两次。

http://technet.microsoft.com/en-us/library/ms186243(v=SQL.105).aspx