MSSQL Присоединиться к GROUP BY слишком медленно - PullRequest
2 голосов
/ 22 апреля 2009

У меня есть следующий запрос в MSSQL

SELECT TOP 50 CustomerID FROM Ratings
WHERE CustomerID != 915
AND MovieID IN (SELECT DISTINCT MovieID FROM Ratings WHERE CustomerID = 915)
GROUP BY CustomerID
ORDER BY count(*) DESC

Это супер быстро. Когда я пытаюсь использовать его в таком подзапросе, как этот.

SELECT * FROM Ratings
WHERE MovieID = 1 AND
CustomerID IN (SELECT TOP 50 CustomerID FROM Ratings
    WHERE CustomerID != 915
    AND MovieID IN (SELECT DISTINCT MovieID FROM Ratings WHERE CustomerID = 915)
    GROUP BY CustomerID
    ORDER BY count(*) DESC)

Есть идеи, почему это так медленно и как я могу ускорить это? Мой основной ключ (MovieID-CustomerID), и я добавил индекс для CustomerID

1 Ответ

5 голосов
/ 22 апреля 2009

Вам нужно будет создать дополнительный индекс UNIQUE для (CustomerID, MovieID) (в этом порядке), чтобы улучшить этот запрос.

Подробнее о производительности смотрите в статье в моем блоге:

Поскольку ваши подзапросы возвращают UNIQUE наборов значений, запрос может быть переписан как JOIN:

SELECT  r2.*
FROM    (
        SELECT  TOP 50 CustomerID
        FROM    (
                SELECT  MovieID
                FROM    Ratings
                WHERE   CustomerID = 915
                ) q
        JOIN    Ratings r
        ON      r.MovieID = q.MovieID
                AND CustomerID <> 915
        GROUP BY
                CustomerID
        ORDER BY
                COUNT(*) DESC
        ) ro
JOIN    Ratings r2
ON      r2.MovieID = 1
        AND r2.CustomerID = ro.CustomerID

Чтобы выбрать TOP 50 клиентов из числа тех, кто оценил Movie 1, используйте:

SELECT  r2.*
FROM    (
        SELECT  TOP 50 CustomerID
        FROM    (
                SELECT  MovieID
                FROM    Ratings
                WHERE   CustomerID = 915
                ) q
        JOIN    Ratings r
        ON      r.MovieID = q.MovieID
                AND CustomerID <> 915
                AND EXISTS
                (
                SELECT  1
                FROM    Ratings re
                WHERE   re.MovieID = 1
                        AND re.CustomerID = r.CustomerID
                )
        GROUP BY
                CustomerID
        ORDER BY
                COUNT(*) DESC
        ) ro
JOIN    Ratings r2
ON      r2.MovieID = 1
        AND r2.CustomerID = ro.CustomerID
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...