postgreSQL从一些中间结果中快速随机采样



我需要从满足某些条件的行中进行采样,例如从年龄小于25岁的用户中采样100个用户。

我试着关注这里的帖子https://www.sisense.com/blog/how-to-sample-rows-in-sql-273x-faster/并根据行号给每个中间结果一个intermediate_id,但查询(在7M条目表上(非常慢(超过2秒(。有什么更好的方法?这是我的尝试:

with relevant_users as (select *,ROW_NUMBER() OVER () as intermediate_id from users where age<25),
relevant_users_count as (select count(*) from relevant_users) 
select * from relevant_users
where intermediate_id in (
select round(random() * (select * from relevant_users_count) )::integer as intermediate_id
from generate_series(1, 110)
group by intermediate_id -- Discard duplicates
)
limit 100

如果你想要100个年龄小于25岁的随机用户,我的第一个建议是:

select u.*
from users u
where age < 25
order by random()
limit 100;

或者另一种不对所有数据进行排序的方法是:

select u.*
from users u cross join
(select count(*) as cnt from users where age < 25) x
where age < 25 and
x < 2 * 100 / cnt
order by random()
limit 100;

这将获取大约200行,然后对最后的100行进行排序。

如果没有WHERE条款,我的建议是TABLESAMPLE。如果您有一个非常大的表,并且知道相当多的用户年龄在25岁以下,那么在采样之前,这可能仍然可以减少行数。

最新更新