Один из способов сделать это:
SELECT *, (SELECT count(*) FROM tbl) AS ct
FROM tbl
ORDER BY random()
LIMIT 1;
Если таблица огромна, а производительность - проблема, есть способы ускорить случайный выбор. Наличие последовательного столбца без пробелов очень поможет в этом ...
Если это для вас, взгляните на этот связанный ответ: Случайная строка в MySQL
Работает и в PostgreSQL. Замените random()
на rand()
.
.
Кстати, функция random()
работает абсолютно независимо от количества строк.
Вот вариант, который производит то же самое только с одним последовательным сканированием:
SELECT *, count(*) OVER () AS ct
FROM ef.adr
ORDER BY random()
LIMIT 1;
Однако быстрый тест с таблицей из 5 тыс. Строк был медленнее.
Еще один с таблицей из 400 тысяч строк показывает аналогичный результат. немного медленнее. Оконные функции могут влиять на производительность. И считается, что count (*) довольно медленный для больших таблиц в PostgreSQL, потому что каждый кортеж должен быть посещен.
Сканирование только по индексу («покрывающие индексы») недавно было реализовано в версии 9.2 devel. Таким образом, мы ожидаем ускорения со следующей версией здесь. Подробнее об этом можно прочитать в сообщении на dba.stackexchange.com :
Между тем, 230 мс для таблицы 400 Кб не так уж и плохи.