如何优化从JOIN获取的集合中选择一个随机行

时间:2017-05-20 19:09:24

标签: postgresql

用英语查询:

  • stuff 中检索随机行。
  • 完成时未提及
  • 行。
  • 行属于得分最高的朋友 *如果找不到属于得分最高的朋友的行,请选择下一位朋友,依此类推。

我当前的查询需要很长时间才能完成,因为它会随机排序所有内容,而它应该批量批量随机排序。

这是一个包含表格和数据的sqlfiddle

我的查询:

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;

1 个答案:

答案 0 :(得分: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