Как получить ВСЕ пользовательские теги сообщений (включая теги ответов) в Stack Exchange Data Explorer?

Я использую запрос в обозревателе данных стека Exchange (SEDE).

Это мой запрос:

SELECT A.Id
       , A.PostTypeId
       , A.Title
       , A.Body
       , A.ParentId
       , A.Tags
       , A.CreationDate
FROM   posts A
       LEFT JOIN users U
              ON A.OwnerUserId = U.id
WHERE  U.Id = ##UserId##
       AND A.PostTypeId = 1
UNION
SELECT A.Id
       , A.PostTypeId
       , A.Title
       , A.Body
       , A.ParentId
       , B.Tags
       , A.CreationDate
FROM   posts A
       LEFT JOIN users U
              ON A.OwnerUserId = U.id
       RIGHT JOIN posts B
               ON A.ParentId = B.Id
WHERE  U.Id = ##UserId##
       AND A.PostTypeId = 2

В приведенном выше коде сообщения в переполнении стека имеют 2 типа: вопрос и ответ. Вопросы(PostTypeId 1 в схеме базы данных) есть теги, но ответы (PostTypeId 2 в схеме базы данных) не имеют тегов. Ответы относятся к вопросам через ParentId,

Но эффективность моего запроса выше слишком низкая, я могу получить только некоторые (используя идентификатор пользователя) теги сообщений.

Как я могу получить теги сообщений всех пользователей за время SEDE?

1 ответ

Несколько вещей:

  1. Вы не можете получить теги всех сообщений пользователя. В настоящее время насчитывается более 41 миллиона сообщений, и SEDE ограничивает результаты до 50000 строк.
  2. Итак, вам нужно: (A) каким-то образом ограничить результаты или (B) пролистать до 41 млн сообщений, по 50 Кб за раз (НЕ РЕКОМЕНДУЕТСЯ), или (C) использовать вместо этого Дамп данных или Google BigQuery($).
  3. Если вы не собираетесь ничего вытаскивать из Users таблица, но ID, то не включайте эту таблицу. Это жует циклы и Posts.OwnerUserId это то же самое.
  4. избежать UNION заявления по возможности (именно в этом случае).
  5. При использовании UNION заявления, использовать UNION ALL если возможно (именно в этом случае). Это избавляет двигатель от необходимости делать повторные проверки.

Итак, вот план выполнения для исходного запроса:

до

Вот упрощенный план:

И соответствующий ему запрос:

SELECT      TOP 50000
            p.OwnerUserId                                       AS [User]
            , p.Id                                              AS [Post Id]
            , CASE WHEN p.PostTypeId = 1 THEN 'Q' ELSE 'A' END  AS [Type]
            , COALESCE (p.Title, ownr.Title)                    AS [Title]
            , p.Body
            , COALESCE (p.Tags, ownr.Tags)                      AS [Tags]
            , p.CreationDate
FROM        Posts p
LEFT JOIN   Posts ownr      ON ownr.ID = p.ParentId
WHERE       p.OwnerUserId   = ##UserId##
AND         p.PostTypeId    IN (1, 2)  -- Question, answer
ORDER BY    p.OwnerUserId DESC,  p.CreationDate

- что также дает более читаемые результаты - особенно когда WHERE пункт удален.

Но, если вы можете ограничить, скажем, пользователем заранее; Вы получаете еще более эффективный запрос:

WITH usersOfInterest AS (
    SELECT      TOP 10
                u.Id                                                AS [UserId]
                , u.DisplayName
    FROM        Users u
    ORDER BY    u.Reputation DESC
)
SELECT      
            [User] = 'site://u/' + CAST(u.UserId AS NVARCHAR) + '|' + CAST(u.UserId AS NVARCHAR)
            , p.Id                                              AS [Post Id]
            , CASE WHEN p.PostTypeId = 1 THEN 'Q' ELSE 'A' END  AS [Type]
            , COALESCE (p.Title, ownr.Title)                    AS [Title]
            , p.Body
            , COALESCE (p.Tags, ownr.Tags)                      AS [Tags]
            , p.CreationDate
FROM        usersOfInterest u
INNER JOIN  Posts p         ON u.UserId = p.OwnerUserId
LEFT JOIN   Posts ownr      ON ownr.Id  = p.ParentId
WHERE       p.PostTypeId    IN (1, 2)   -- Question, answer
ORDER BY    u.UserId DESC,  p.CreationDate

(Этот запрос добавляет удобную гиперссылку на идентификатор пользователя.)

Обратите внимание, что только 10 лучших пользователей имеют более 50 тыс. Сообщений.

Другие вопросы по тегам