If the order should be “jumbled”, but not randomly ...
( Update: see my other answer for a more flexible and randomized solution. )
You say the "random" order that you get when you call ORDER BY random() - for each row, PostgreSQL calls random() , gets the value and uses it to decide how to sort that row in the result set.
To make it repeatable, you have to mess with the seeds. It looks indecent. According to the docs :
effects will remain until the end of the session if they are not canceled by another SET
I think this means that when using the connection pool setseed connection is for the next process that uses this connection.
What is modulo?
I have a case when I do not need real randomness. My criteria:
- not the same order every time
- predictable ordering on pages of the same result set so that we don't get duplicates on subsequent pages
For example, this would be good:
- Listing 1
- page 1: paragraphs 1, 4
- page 2: paragraphs 3, 2
- Listing 2 (another user or same user coming back later)
- page 1: paragraphs 3, 1
- page 2: paragraphs 2, 4
To get something like this, modulo seems to work well. For example, ORDER BY id % 7, id for all pages of query 1 and ORDER BY id % 11, id for all pages of query 2. That is, for each row, divide your identifier modulo and sort by the remainder. In rows with the same remainder, sort by id (to ensure sort stability).
The module can be randomly selected for the first page, and then reused as a parameter for each subsequent page request.
You can see how this might work for your database, for example:
echo "select id, id % 7 FROM my_table ORDER BY id % 77, id" | psql my_db > sort.txt
The main module is likely to give you the biggest change. And if your identifiers begin with 1 (so that % 77 returns the first 77 lines in the normal order), you could instead try to execute a module for the timestamp field. For instance:
ORDER BY (extract(epoch from inserted_at)* 100000)::bigint % 77
But you need a function index to make it fast.