use*_*521 12 random postgresql pagination random-seed
我有API从DB返回圆顶分页行.它工作正常,但是当我按行排序时,RANDOM()我会在连续的页面上重复.是否有任何选项可以为每个查询设置随机种子?
如果不是可以全局设置随机SEED以强制RANDOM()为每个查询生成相同的值?然后我可以每隔3分钟改变全局随机或类似的东西......
你用这个代码:
SELECT * FROM "table" ORDER BY RANDOM() OFFSET 5 LIMIT 5
Run Code Online (Sandbox Code Playgroud)
现在我想传递种子到这个查询,所以我可以分页随机结果.我应该这样做?:
SELECT "table".*, SETSEED(0.1) FROM "table" ORDER BY RANDOM() OFFSET 5 LIMIT 5
SELECT "table".*, SETSEED(0.1) FROM "table" ORDER BY RANDOM() OFFSET 10 LIMIT 5
Run Code Online (Sandbox Code Playgroud)
结果将正确分页?
你说"随机"顺序,这是你在调用时获得的ORDER BY random()- 对于每一行,PostgreSQL调用random(),获取一个值,并使用它来决定如何在结果集中对该行进行排序.
为了使这个可重复,你必须弄乱种子.这感觉很蠢.根据文件:
效果将持续到会话结束,除非被另一个SET覆盖
我认为这意味着在使用连接池时,会setseed改变使用该连接的下一个进程的连接.
我有一个案例,我不需要真正的随机性.我的标准是:
例如,这没关系:
为了获得这样的东西,模数似乎运作良好.例如,ORDER BY id % 7, id对于请求1 ORDER BY id % 11, id的所有页面,以及请求2的所有页面.即,对于每一行,将其id除以模数并按余数排序.在具有相同余数的行中,按id排序(以确保排序稳定).
可以为第一页随机选取模数,然后将其重新用作每个后续页面请求的参数.
你可以看到这对你的数据库如何有用:
echo "select id, id % 7 FROM my_table ORDER BY id % 77, id" | psql my_db > sort.txt
Run Code Online (Sandbox Code Playgroud)
素数模数可能会给你最大的变化.如果你的id从1开始(这样% 77会使前77行以正常顺序返回),你可以尝试在时间戳字段上执行模数.例如:
ORDER BY (extract(epoch from inserted_at)* 100000)::bigint % 77
但是你需要一个函数索引来提高性能.
使用这种union all技术,随机顺序是可重复的
select a, b
from (
select setseed(0.1), null as a, null as b
union all
select null, a, b
from t
offset 1
) s
order by random()
offset 0
limit 5
;
Run Code Online (Sandbox Code Playgroud)
您可以使用[-1.0, 1.0] 中的种子进行setseed(dp)播种。random()例如:
engine=> SELECT SETSEED(0.16111981);
setseed
---------
(1 row)
engine=> SELECT RANDOM();
random
-------------------
0.205839179921895
(1 row)
engine=> SELECT RANDOM();
random
-------------------
0.379503262229264
(1 row)
engine=> SELECT RANDOM();
random
-------------------
0.268553872592747
(1 row)
engine=> SELECT RANDOM();
random
-------------------
0.788029655814171
(1 row)
Run Code Online (Sandbox Code Playgroud)
当然,每次重新播种时,您都会得到完全相同的结果:
engine=> SELECT SETSEED(0.16111981), RANDOM();
setseed | random
---------+-------------------
| 0.205839179921895
(1 row)
engine=> SELECT SETSEED(0.16111981), RANDOM();
setseed | random
---------+-------------------
| 0.205839179921895
(1 row)
engine=> SELECT SETSEED(0.16111981), RANDOM();
setseed | random
---------+-------------------
| 0.205839179921895
(1 row)
engine=> SELECT SETSEED(0.16111981), RANDOM();
setseed | random
---------+-------------------
| 0.205839179921895
Run Code Online (Sandbox Code Playgroud)
(澄清:输出是从 复制的psql,引擎是我的数据库的名称)
| 归档时间: |
|
| 查看次数: |
2057 次 |
| 最近记录: |