如何在Stack Exchange Data Explorer中获取所有用户帖子的标签(包括答案​​的标签)?

时间:2018-09-23 08:30:14

标签: sql sql-server sql-server-2017 dataexplorer

我在Stack Exchange Data Explorer(SEDE)中使用查询。

这是my query

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

在上面的代码中,Stack Overflow中的帖子有2种类型:问题和答案。 Questions(PostTypeId在数据库模式中为1)具有标签,但是答案(PostTypeId在数据库模式中为2)没有标签。 答案属于通过ParentId提出的问题。

但是我上面的查询的效率太低,我只能(使用用户ID)获得一些帖子的标签。

如何在SEDE超时内获取所有用户帖子的标签?

1 个答案:

答案 0 :(得分:0)

几件事:

  1. 您无法获取所有用户帖子的标签。当前是there are over 41 million postsSEDE limits results to 50,000 rows
  2. 因此,您需要:(A)以某种方式限制结果,或者(B)page through个4100万帖子,一次5万(不推荐),或(C)使用改为the Data DumpGoogle's BigQuery($)
  3. 如果您不打算从Users表中提取任何东西,但要提取ID,则不要包括该表。它缩短了周期,Posts.OwnerUserId是一回事。
  4. 尽可能避免使用UNION语句(在这种情况下)。
  5. 如果使用UNION语句,请尽可能使用UNION ALL(在这种情况下)。这使引擎不必进行重复检查。

因此,这是原始查询的执行计划:

before

这是精简计划:

enter image description here

还有the query that corresponds to it

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子句时。

但是,如果您可以事先限制用户的话;您得到偶数more efficient query

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

(此查询adds a convenient hyperlink对用户ID。)

请注意,只有排名前10位的用户拥有超过5万条帖子。