我在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超时内获取所有用户帖子的标签?
答案 0 :(得分:0)
几件事:
Users
表中提取任何东西,但要提取ID,则不要包括该表。它缩短了周期,Posts.OwnerUserId
是一回事。UNION
语句(在这种情况下)。UNION
语句,请尽可能使用UNION ALL
(在这种情况下)。这使引擎不必进行重复检查。因此,这是原始查询的执行计划:
这是精简计划:
还有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万条帖子。