Django как перетасовать набор запросов без потери скорости
Я хочу перетасовать список объектов без потери скорости в плане оптимизации и скорости работы. Допустим, у меня есть следующий запрос.
related_products = Announcement.objects.filter(category=category).exclude(id=announcement.id)
pythonically, я бы импортировал модуль random и затем random.shuffle(related_products)
. Но я не уверен, будет ли он хранить что-то в памяти на моем представлении или использовать скорость процессора или какую-то другую терминологию, я не знаю.
Так что мне интересно, какой лучший способ сделать его оптимизированным.
Спасибо!
Если список объектов related_products достаточно короткий и если вы собираетесь использовать их все в любом случае, проще всего просто получить их, а затем перетасовать.
import random
...
products = random.shuffle( list( related_products) )
for product in products:
...
Это эффективно, поскольку никакие объекты не копируются. Основная проблема заключается в том, что количество может быть избыточным. Вы можете использовать related_products.count()
, чтобы узнать их количество, прежде чем получить любой из них из БД.
Существует также queryset .order_by('?')
, который извлекает информацию в случайном порядке, но в документации говорится: "Примечание: запросы order_by('?') могут быть дорогими и медленными, в зависимости от используемой вами базы данных"
Третьим вариантом выборки может быть выборка только первичных ключей каждой строки таблицы. Перемешайте и нарежьте их, чтобы получить выборку нужного размера, а затем возьмите только эти объекты.
product_pks = related_products.values_list('pk', flat=True)
sampled_pks = random.shuffle( list(product_pks))[:N_SAMPLE]
products = related_products.filter( pk__in = sampled_pks )
Не знаю, как это будет работать, но это два запроса к БД, и первый из них извлекает минимальное количество данных, необходимых для перетасовки.