是否可以 select 对特定列稍加偏好的随机行?

Would it be possible to select random rows with a little preference for a specific column?

我想从我的 table 中随机选择记录,但我想知道是否可以为新创建的项目提供更好的机会。我也有分页,所以这就是我使用 setseed

的原因

目前我只是随机检索项目并且效果很好,但我需要对新创建的项目给予一定的“偏好”。

这是我现在正在做的事情:

SELECT SETSEED(0.16111981), RANDOM();

我不知道该怎么做,我想不出什么是好的解决方案而不是绝对的性能灾难。

首先我想解释一下我们如何在 table 上 select 随机记录。在 PostgreSQL 上,我们可以在 order by 语句中使用 random() 函数。示例:

select * from test_table
order by random()
limit 1;

我只使用 limit 1 来 select 记录一条记录。但是,使用这种方法我们的查询性能对于大尺寸 tables(超过 1 亿数据)

会非常糟糕

第二种方法,如果 table 有 id 字段,您可以使用 random() 手动 selecting 记录。这种方式是非常高性能的。 让我们首先编写我们自己的随机化函数,以便在我们的查询中轻松使用它。

CREATE OR REPLACE FUNCTION random_between(low integer, high integer)
 RETURNS integer
 LANGUAGE plpgsql
 STRICT
AS $function$
BEGIN
   RETURN floor(random()* (high-low + 1) + low);
END;
$function$;

这个函数returns一个random我们输入参数值范围内的整数值。然后我们可以使用随机函数编写查询。示例:

select * from test_table 
where id = (select random_between(min(id), max(id)) from test_table);

我在 table 上测试的这个查询有 1.5 亿条数据并获得最佳性能,持续时间 12 毫秒。在这个查询中,如果你需要很多行而不是一个,那么你可以写 where id > 而不是 where id=.

现在,为了您的小小喜好,我不知道您要设置为随机化的详细业务逻辑和条件语句。我可以为您编写一些示例查询以了解该机制。 PostgreSQL 没有执行此过程的功能,因此使用首选项随机化数据。我们必须手动编写此逻辑。我创建了一个样本 table 来测试我们的查询。

CREATE TABLE test_table (
    id serial4 NOT NULL,
    is_created bool NULL,
    action_date date NULL,
    CONSTRAINT test_table_pkey PRIMARY KEY (id)
);
CREATE INDEX test_table_id_idx ON test_table USING btree (id);

例如,我只想对操作日期最接近今天的数据设置更多偏好。示例查询:

select 
    id, 
    is_created, 
    action_date, 
    (extract(day from (now()-action_date))) as dif_days 
from 
    test.test_table
where 
    id > (select random_between(min(id), max(id)) from test.test_table)
    and 
    (extract(day from (now()-action_date))) = random_between(0, 6)
limit 1;

在此查询中,此 (extract(day from (now()-action_date))) as dif_days 查询将返回 action_date 与今天之间的差异。在 where 子句中,首先我 select 数据是 id 字段值大于生成的随机化值。然后使用这个查询 (extract(day from (now()-action_date))) = random_between(0, 6) 我 select 从这个结果数据中只有数据 action_date 等于最大 6 天前(可能是 4 天前或 2 天前,6 天前)。

Сan 编写了许多逻辑查询(例如使用布尔字段设置更多首选项:关闭打开等)