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
部分扩展了您的答案。这是我的建议。请指出任何可能的改进。好的,对不起。我已将其添加到答案中。