简体   繁体   中英

Optimizing query to improve performance

How to optimize the following SQL query? I have this query which works but I need to optimize it, or do you have a suggestion for an online SQL refactoring tool?

Table: Membership

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

Table: content_group_membership

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

The Membership table holds the list of groupID the user belongs to and the content_group_membership table hold the list of permitted ContentID for the corresponding groupID .

We need to get the list of contentID which are restricted for that user, groupID for the UserID should be taken from Membership table and the contentID with groupID of other than user's groupID are restricted ContentID for that UserID .

Below is the query, right now we are using which is consuming triple the amount of time consumed to fetch the result when the below query is used as sub query. So, we want an optimized query to fetch results quickly.

Expected result : 33333

Query:

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)) 

This should be equivalent, and run more efficiently:

 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)) 

However, a query of this complexity might be better off as a procedure.

I don't have enough reputions to comment, so, it will do this as an answer.

I believe this query is primed for a CTE so it doesn't have to executed twice.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM