我想在大型数据集(> 30万亿行)中选择一行,并且写入/读取次数很多。
我的问题我不能让任意选择postgresql(这本来是最便宜/最快的查询,使用'限制1')因为它的行为不正常和不明确的方式":在这里看到我最初的问题:postgresql 9.4 - prevent app selecting always the latest updated rows
这是我当前的查询
UPDATE opportunities s
SET opportunity_available = false
FROM (
SELECT id
FROM opportunities
WHERE deal_id = #{@deal.id}
AND opportunity_available
AND pg_try_advisory_xact_lock(id)
LIMIT 1
FOR UPDATE
) sub
WHERE s.id = sub.id
RETURNING s.prize_id, s.id;
// inspired by https://stackoverflow.com/questions/33128531/put-pg-try-advisory-xact-lock-in-a-nested-subquery
我问了第一个问题(postgresql 9.4 - prevent app selecting always the latest updated rows),但我认为即使没有明确的答案,发生的事情是postgresql可以自由选择(因为我只使用'限制1'因为我想要最便宜/最快的查询),这与RANDOM选择非常不同。但结果是,postgresql经常输出管理员更新的最新行(总是有机会获得所有奖品),而不是随机选择行。
我想我需要离开任意选择以获得RANDOM选择。
在这种情况下,最好的选择是什么,即最快的选择(注意' FOR UPDATE'和#39;咨询锁'因为我需要在更新时锁定行更新以防止并发调用...我很快就会在postgresql 9.5中使用,一旦9.5退出测试版,就会跳过锁定)
使用带有random()的顺序,但是很明显(在stackoverflow和堆栈交换dba上阅读很多关于此的帖子)在大数据集上真的很慢=> " ORDER BY RAND()很慢,因为DBMS必须读取所有行,对它们进行排序,只保留几行。因此,此查询的性能在很大程度上取决于表中的行数,并随着行数的增加而减少。",如解释here或here
对于大型数据集,使用偏移的速度也很慢
使用采样,就像在这里解释/建议的大专家一样:https://www.periscopedata.com/blog/how-to-sample-rows-in-sql-273x-faster.html
使用您可能建议的其他高级技术