繁体   English   中英

Select 根据给定标准的随机行 PostgreSQL

[英]Select random rows according to a given criteria PostgreSQL

我有一千万行的表user 它有字段: id int4 primary keyrating int4country varchar(32)last_active timestamp 它在标识符上有差距。 任务是 select 给定国家/地区的五个随机用户,这些用户在过去两天内活跃并在给定范围内评级。 有没有比下面的查询更快的 select 它们的棘手方法?

SELECT id
FROM user
WHERE last_active > '2020-04-07'
    AND rating between 200 AND 280
    AND country = 'US'
ORDER BY random()
LIMIT 5

它想到了这个查询:

SELECT id
FROM user
WHERE last_active > '2020-04-07'
    AND rating between 200 AND 280
    AND country = 'US'
    AND id > (SELECT random()*max(id) FROM user)
ORDER BY id ASC
LIMIT 5

但问题是有很多非活动用户的标识符值很小,大多数新用户都在 id 范围的末尾。 因此,此查询将 select 一些用户过于频繁。

根据 EXPLAIN 计划,您的表很大。 每页大约 2 行。 要么它非常臃肿,要么行本身非常宽。

获得良好性能的关键可能是让它使用仅索引扫描,方法是创建一个包含查询中引用的所有 4 列的索引。 测试相等性的列应该放在第一位。 之后,您必须在两个范围或不等式查询列(“last_active”或“rating”)之间进行选择,具体取决于您认为更具选择性的列。 然后将另一个范围或不等式和 id 列添加到末尾,以便可以使用仅索引扫描。 所以也许create index on app_user (country, last_active, rating, id) 那可能就足够了。

您还可以在这些相同的列上尝试 GiST 索引。 这具有理论上的优势,即两个范围或不等式限制可以一起用于定义要查看的索引页面。 但在实践中,GiST 索引具有非常高的开销,而且这种开销可能会超过理论上的收益。

如果以上还不够好,您可以尝试分区。 但是你应该如何做到这一点应该基于你的应用程序的整体视图,而不仅仅是一个查询。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM