Horai Nuri
Horai Nuri

Reputation: 5578

How to get many numbers of random records from database?

I know this question has been asked many times, but most of the answers use this method : MyModel.objects.order_by('?')[:4] which will kill the database in the second day of production.

I'm looking for a faster and lightweight solution, I'm using the one below for now, but I would like to get more than 1 random query (4 for example).

views.py

last = MyModel.objects.count() - 1
random_int = random.randint(0, last)
records = MyModel.objects.all()[random_int] #one record only

Any solution ?

Upvotes: 0

Views: 72

Answers (3)

knbk
knbk

Reputation: 53699

As long as you need a reasonable number of elements (such as 4), I'd sample based on the queryset index rather than the id. The drawback is that you need 4 queries instead of 1, but this way you get a consistent performance that doesn't depend on the number and size of gaps in between your primary key values.

count = MyModel.objects.count()
sample =  random.sample(range(count), 4)
records = [MyModel.objects.all()[i] for i in sample]

Indexing a queryset uses LIMIT and OFFSET, so the indexing is based on the number of rows in the database, not on the id.

Upvotes: 2

iklinac
iklinac

Reputation: 15738

Use in keyword and generate random sample of numbers

random_num_sample =  random.sample(range(0, last), 4)
records = MyModel.objects.filter(id__in=random_num_sample)

If the database gets frequent deletes than this solution is not viable, If deletes are not moderate you can still use following by randomizing sample with more than 4 elements

Upvotes: 2

Arpit Solanki
Arpit Solanki

Reputation: 9931

You can use in keyword.

random_num = [random.randint(0, last) for i in range(4)]

Then use

queryset_obj = MyModel.objects.filter(id__in=random_num)

Upvotes: 1

Related Questions