我试图检查表格列中的数字分布。我想通过重复采样来估算整个表(大到几十千兆字节)而不是计算。我认为典型的Postgres方法是
select COLUMN
from TABLE
order by RANDOM()
limit 1;
但这对于重复采样来说很慢,特别是因为(我怀疑)它每次运行时都会操纵整个列。
有更好的方法吗?
编辑:为了确保我表达正确,我想做以下事情:
for(i in 1:numSamples)
draw 500 random rows
end
每次都不必重新排序整个大表。也许我可以在R或其他东西中获取所有表行ID和样本,然后只是请求那些行?
答案 0 :(得分:0)
如果你想要一个数据样本,那么使用表的估计大小然后计算一个百分比作为样本呢?
表pg_class
存储每个表的行数的估计值(如果我没有弄错的话,由真空过程更新)。
因此,以下内容将从该表中选择所有行的1%:
with estimated_rows as (
select reltuples as num_rows
from pg_class t
join pg_namespace n on n.oid = t.relnamespace
where t.relname = 'some_table'
and n.nspname = 'public'
)
select *
from some_table
limit (select 0.01 * num_rows from estimated_rows)
;
如果你经常这样做,你可能想要创建一个函数,所以你可以做这样的事情:
select *
from some_table
limit (select estimate_percent(0.01, 'public', 'some_table'))
;
答案 1 :(得分:0)
从目标表创建一个临时表,添加行号列
drop table if exists temp_t;
create temporary table temp_t as
select *, (row_number() over())::int as rn
from t
通过仅选择将在采样和过滤中使用的列来创建更轻的临时表。
按行号列
对其进行索引create index temp_t_rn on temp_t(rn);
analyze temp_t;
为每个样本发出此查询
with r as (
select ceiling(random() * (select max(rn) from temp_t))::int as rn
from generate_series(1, 500) s
)
select *
from temp_t
where rn in (select rn from r)