Получить первые 1 и 2 записи из каждой группы из таблицы - PullRequest
0 голосов
/ 11 ноября 2011

У меня есть запрос, который должен получить первый и второй по величине sku в каждом списке пожеланий участников. Приведенный ниже запрос работает, но он занимает слишком много времени, поскольку у него около 9 миллионов пользователей, и у каждого пользователя есть около 10 элементов списка желаний, поэтому вы можете видеть, что приведенный ниже запрос никогда не завершится.

SELECT MAX(CASE WHEN wl.rank = 1 THEN wl.SKU ELSE NULL END) AS [highestSku],
       MAX(CASE WHEN wl.rank = 2 THEN wl.SKU ELSE NULL END) AS [secondHighestSku],
FROM Member m
     LEFT JOIN (SELECT *
                 FROM (SELECT DENSE_RANK() OVER (PARTITION BY wl.MemberID ORDER BY wli.Price DESC) AS rank, wl.MemberID, wli.SKU
                       FROM WishListItem wli
                            INNER JOIN WishList wl ON wli.WishListID = wl.ID) T1) w ON w.MemberID = m.ID

У меня вопрос: есть ли лучший способ получить первые и вторые записи для каждого пользователя? Если нет, то есть ли способ оптимизировать этот запрос? В идеале, если я смогу уменьшить количество таймов, извлеченных из запроса ранжирования (с помощью DENSE_RANK ()), это поможет мне. Я хотел сделать что-то вроде WHERE DENDS_RANK () <= 2, но это невозможно, и выполнение этого за скобками наносит ущерб цели души. </p>

Кроме того, это только часть запроса. На самом деле у меня осталось еще больше объединений в большем количестве таблиц, которые содержат столько же элементов, и мне нужно получить первые 1 и 2 записи для каждого пользователя.

И это нужно сделать в одном запросе или в максимально возможной степени в одном, потому что я добавляю его в таблицу данных. Я также могу уменьшить количество записей, т.е. TOP 1000 и разбить запрос, но мне нужно будет продолжить с того места, где я остановился ... также я попробовал TOP 1000, и через 10 минут я отменил запрос, потому что мне нужно получить все 9 миллионов записей.

1 Ответ

0 голосов
/ 04 февраля 2012

Я бы взял сравнительно небольшое подмножество данных, вставил бы его в табличную переменную и выполнил бы запрос из этой основной (и, вероятно, очень «занятой») таблицы:

DECLARE @Member TABLE
(
    ID int IDENTITY (1, 1) PRIMARY KEY NOT NULL,
    -- add necessary columns to this definition.
)

INSERT INTO @Member (field1, field2...)
SELECT field1, field2  -- etc. 
FROM YourTables
WHERE SomeCriteria = Whatever

Убедитесь, что предложение WHERE определяет более узкое подмножество данных, чем ваши производственные таблицы. Если производительность все еще страдает, вы можете создать переменные таблицы для других таблиц, к которым вы присоединяетесь, а затем использовать их в конечном запросе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...