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

Я использую запрос в Stack Exchange Data Explorer (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 Ответ

0 голосов
/ 24 сентября 2018

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

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

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

before

Вот оптимизированный план:

enter image description here

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

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 тыс. сообщений.

...