Postgresql 如何优化从JOIN获取的集合中选择一个随机行
英文查询:Postgresql 如何优化从JOIN获取的集合中选择一个随机行,postgresql,Postgresql,英文查询: 从资料中检索随机行 “完成”中未提及行 行属于得分最高的朋友 *如果没有找到属于得分最高的朋友的行,则选择下一个朋友,以此类推 我当前的查询需要很长时间才能完成,因为它是对所有东西进行随机排序,而它应该一批一批地随机排序 下面是一个包含表和数据的示例 我的问题是: WITH ordered_friends AS (SELECT * FROM friends ORDER BY sco
- 从资料中检索随机行
- “完成”中未提及行
- 行属于得分最高的朋友 *如果没有找到属于得分最高的朋友的行,则选择下一个朋友,以此类推
WITH ordered_friends AS (SELECT *
FROM friends
ORDER BY score DESC)
SELECT s.stuff_id
FROM ordered_friends
INNER JOIN (SELECT *
FROM stuff
ORDER BY random()) AS s ON s.owner = ordered_friends.friend
WHERE NOT EXISTS(
SELECT 1
FROM done
WHERE done.me = 42
AND done.friend = s.owner
AND done.stuff_id = s.stuff_id
)
-- but it should keep the order of ordered_friends (score)
-- it does not have to reorder all stuff
-- one batch for each friend is enough until a satisfying row is found.
LIMIT 1;
这个怎么样
SELECT s.stuff_id
FROM friends
CROSS JOIN LATERAL (SELECT stuff_id
FROM stuff
WHERE stuff.owner = friends.friend
AND NOT EXISTS(SELECT 1
FROM done
WHERE done.me = 42
AND done.friend = stuff.owner
AND done.stuff_id = stuff.stuff_id
)
ORDER BY random()
LIMIT 1
) s
ORDER BY friends.score DESC
LIMIT 1;
以下索引将使其速度更快:
CREATE INDEX ON friends(score); -- for sorting
CREATE INDEX ON stuff(owner); -- for the nested loop
CREATE INDEX ON done(stuff_id, friend); -- for NOT EXISTS
谢谢你的回答。但有一个问题:它没有过滤掉表done中提到的内容。我通过添加
notexists
部分扩展了您的答案。这是我的建议。请指出任何可能的改进。好的,对不起。我已将其添加到答案中。