Случайная запись из таблицы в Postgresql
Таблица может содержать как десятки миллионов строк, так и всего несколько. Нужно быстро выбрать одну случайную строку.
Что пробовал, и что не получалось:
SELECT * FROM table ORDER BY RAND() LIMIT 1
Не подходит, т.к. просматривает всю таблицу. Слишком долго.
SELECT * FROM table
OFFSET (floor(random() * (SELECT COUNT(*) FROM table)))
LIMIT 1
Тоже долго работает.
SELECT * FROM table WHERE id >= RAND() *
( SELECT MAX (id) FROM table )
ORDER BY id LIMIT 1
Благодаря индексам может работать за логарифм. Но не подходит, т.к. нет гарантий, что id будут равномерно распределены (вернее 100% не будут, поскольку данные регулярно добавляются и удаляются).
SELECT * FROM table TABLESAMPLE SYSTEM (N) LIMIT 1
Пока что самый убедительный вариант, работает быстро. Но есть и нюансы. При выставлении большого N рандом становится ужасным. На 1000 сгенерированных записей уникальных было только 200-300 на таблице из десятков миллионов записей. При выставлении же маленького N перестает работать на маленьких таблицах, где только пару сотен строчек записей, просто ничего не возвращает.
Postgres же операционная система, помогите