Un order by
siempre será costoso, especialmente si la expresión en el orden por no está indexada. Así que no ordenes. En su lugar, haga un desplazamiento aleatorio en el count()
como en sus consultas, pero hágalo todo de una vez.
with t as (
select *
from
products p
inner join
images i using (productid)
where
prodtype = $sometype
)
select *
from t
offset floor(random() * (select count(*) from t))
limit 1
Esta versión podría ser más rápida
with t as (
select *, count(*) over() total
from
products p
inner join
images i using (productid)
where
prodtype = $sometype
)
select *
from t
offset floor(random() * (select total from t limit 1))
limit 1