Sql 我将从mytable中为您提供5%的元素

Sql 我将从mytable中为您提供5%的元素,sql,performance,postgresql,random,Sql,Performance,Postgresql,Random,请参阅有关文档的更多说明: 如果您知道需要多少行,请查看。 tsm_系统_行 模块提供表采样方法SYSTEM_ROWS,可在SELECT命令的TABLESAMPLE子句中使用 此表采样方法接受单个整数参数,该参数是要读取的最大行数。结果样本将始终精确地包含那么多行,除非表中没有足够的行,在这种情况下,将选择整个表与内置系统采样方法一样,SYSTEM_行执行块级采样,因此样本不是完全随机的,但可能会受到聚类影响,特别是在仅请求少量行的情况下。 首先安装扩展 CREATE EXTENSION tsm

请参阅有关文档的更多说明:

如果您知道需要多少行,请查看。

tsm_系统_行 模块提供表采样方法SYSTEM_ROWS,可在SELECT命令的TABLESAMPLE子句中使用

此表采样方法接受单个整数参数,该参数是要读取的最大行数。结果样本将始终精确地包含那么多行,除非表中没有足够的行,在这种情况下,将选择整个表与内置系统采样方法一样,SYSTEM_行执行块级采样,因此样本不是完全随机的,但可能会受到聚类影响,特别是在仅请求少量行的情况下。

首先安装扩展

CREATE EXTENSION tsm_system_rows;
那么你的提问,

SELECT *
FROM table
TABLESAMPLE SYSTEM_ROWS(1000);

这是一个适合我的决定。我想这很容易理解和执行

SELECT 
  field_1, 
  field_2, 
  field_2, 
  random() as ordering
FROM 
  big_table
WHERE 
  some_conditions
ORDER BY
  ordering 
LIMIT 1000;

我知道我参加聚会有点晚了,但我刚刚发现了一个很棒的工具,名为:

pg_sample
-从更大的PostgreSQL数据库中提取一个小样本数据集,同时保持引用完整性

我用一个350M行的数据库尝试了这个方法,速度非常快,我不知道随机性

/pg\U sample--limit=“small\U table=*”--limit=“large\U table=100000”-U postgres source\U db | psql-U postgres target\U db

我的经验教训:

offset floor(random()*N)limit 1
不快于
order by random()limit 1



我认为
offset
方法会更快,因为它可以节省Postgres排序的时间。事实并非如此。

嗨,杰克,谢谢你的回复,执行时间按顺序会慢一些,但我想知道哪一个是不同的,如果有的话……嗯……不客气。那么,您是否尝试过对不同的方法进行基准测试?还有更快的方法。这完全取决于你的要求和你必须处理的事情。你需要整整1000行吗?该表是否有数字标识?没有/很少/很多差距?速度有多重要?每个时间单位有多少个请求?是否每个请求都需要不同的集合,或者对于定义的时间片,它们可以是相同的?第一个选项“(random()<0.01)”在数学上是错误的,因为如果没有随机数低于0.01,则无法得到任何响应行,这在任何情况下都可能发生(尽管可能性较小),无论表有多大或阈值有多高。第二个选项总是正确的如果您只想选择一行,请参阅以下问题:编写临时文件进行排序的好处。这确实是一个巨大的成功。我想我们可以做
random()<0.02
然后洗牌列表,然后
限制1000
!这种排序在几千行(lol)上花费更少。“select*from table where random()<0.05 limit 500;”是postgresql的一种更简单的方法。我们在一个项目中使用了这一点,我们需要一次选择5%的结果,而不是一次处理500行。为什么在世界上,你会考虑一个O(n)全扫描来检索一个500米行表上的样本吗?它在大型表上的速度慢得可笑,完全没有必要。t表在哪里定义?它应该是r而不是t吗?@LucM:这里定义了它:
joinbigtbl t
,它是
joinbigtblast
的缩写
t
是用于
bigtbl
的。它的目的是缩短语法,但在这种特殊情况下不需要它。我在回答中简化了查询并添加了一个简单的版本。generate_series(11100)中的值范围的用途是什么?@Awesome-o:目标是检索1000行,我从额外的10%开始,以补偿一些间隙或(不太可能但可能)重复的随机数。。。解释在我的回答中。欧文,我发布了你的“可能的替代方案”的一个变体:。我会对你的想法感兴趣。非常有趣。如果我不仅需要选择,而且还需要使用select进行更新,那么使用pg\u try\u advisory\u xact\u锁进行更新,这是否有效?(也就是说,我需要很多并发读写操作)但是没有理由不在第一个示例的末尾添加限制1。唯一的问题是你有可能没有记录,所以你必须在代码中考虑这一点。Fisher Yates的问题是你需要把整个数据集存储在内存中才能从中选择。对于非常大的数据集是不可行的:(我喜欢这个,因为它既短又优雅:)我甚至找到了改进它的方法:解释分析告诉我,像这样,不会使用PKEY索引,因为random()返回一个double,而PKEY需要一个BIGINT.select*,来自于您的_表,其中r>(选择(从pg_类中选择reltuples::bigint作为估算值,其中oid='public.YOUR_TABLE'::regclass)*random()::bigint按r asc限制排序(1);文档中的一个重要注释:"系统方法对具有指定被选择机会的每个块进行块级采样;返回每个选定块中的所有行。当指定较小的采样百分比时,系统方法比伯努利方法快得多,但由于聚类效果,它可能返回较少的表随机样本ects。“有没有办法指定行数而不是百分比?您可以使用
TABLESAMPLE SYSTEM_rows(400)
获得400个随机行的样本。您需要启用以使用此语句。我为您添加的答案添加了一个链接,这是对内置
SYSTEM
方法的显著改进。我刚刚回答了一个问题(随机单记录)在此期间,我执行了相当多的
tsm_系统_行
tsm_系统_时间
扩展。就我所见,它们除了绝对最小的扩展之外,几乎没有任何用处
select * from table where random() < 0.01 limit 1000;
SELECT * FROM f_random_sample();
SELECT * FROM f_random_sample(500, 1.05);
SELECT * FROM big TABLESAMPLE SYSTEM ((1000 * 100) / 5100000.0);
SELECT * FROM big TABLESAMPLE SYSTEM_ROWS(1000);
select your_columns from your_table ORDER BY random()
select * from 
  (select distinct your_columns from your_table) table_alias
ORDER BY random()
select your_columns from your_table ORDER BY random() limit 1
id_values  id  |   used
           ----+--------
           1   |   FALSE
           2   |   FALSE
           3   |   FALSE
           4   |   FALSE
           5   |   FALSE
           ...
select * from YOUR_TABLE 
where r > (
    select (
        select reltuples::bigint AS estimate
        from   pg_class
        where  oid = 'public.YOUR_TABLE'::regclass) * random()
    )
order by r asc limit(1);
SELECT * FROM mytable TABLESAMPLE SYSTEM (5);
select * from table order by random() limit 1000;
CREATE EXTENSION tsm_system_rows;
SELECT *
FROM table
TABLESAMPLE SYSTEM_ROWS(1000);
SELECT 
  field_1, 
  field_2, 
  field_2, 
  random() as ordering
FROM 
  big_table
WHERE 
  some_conditions
ORDER BY
  ordering 
LIMIT 1000;