Django (rest framework) производительность объединения queryset в сравнении с Q в сравнении с другими идеями
Я создаю функцию поиска, которая ищет по нескольким моделям, имеющим отношения к моей основной модели. Используя фреймворк Django rest, я возвращаю постраничный результат по каждому объекту моей основной модели, который связан с поисковым запросом. Поскольку поиск осуществляется с помощью "подстановочных знаков" и в текстовых полях, я хочу сделать его настолько производительным (хорошим?), насколько это возможно.
В настоящее время я реализовал это с помощью объединений кверисетов, думая, что по крайней мере кверисеты загружаются лениво. При попытке реализовать это с помощью Q() мне пришлось пройти через получение фактических идентификаторов ограничений внешнего ключа в виде списков значений (value_lists), и я думаю, что это требует больше вычислений? Но я не очень хорошо понимаю, что к чему с точки зрения производительности.
Чтобы уточнить производительность: Мне нужно низкое использование процессора и памяти на самом хосте (это экземпляры EC2 в AWS), а производительность БД (экземпляр RDS в AWS) меня волнует чуть меньше, но она, конечно, все равно важна.
Итак, вопрос: как сделать так, чтобы это работало наилучшим образом?
Все модели имеют modelMain как обычное ограничение foreingkeyconstraint, за исключением modelB, которая является отношением многие-ко-многим.
Текущий код:
def get_queryset(self):
search_query = self.request.query_params.get('search_query', None)
modelA_used = self.request.query_params.get('modelA', 'not_used')
modelB_used = self.request.query_params.get('modelB', 'not_used')
modelMain_description = self.request.query_params.get('description', 'not_used')
modelMain_subject = self.request.query_params.get('modelMain_subject', 'not_used')
modelC_used = self.request.query_params.get('modelC', 'not_used')
if search_query:
queryset = modelMain.objects.none()
if modelMain_description == 'used':
queryset = queryset.union(modelMain.objects.filter(description__icontains=search_query))
if modelMain_subject == 'used':
queryset = queryset.union(modelMain.objects.filter(subject__icontains=search_query))
if modelA_used == 'used':
modelA_results = modelA.objects.filter(raw_data__icontains=search_query).only('modelMain')
queryset = queryset.union(modelMain.objects.filter(modelA__in=modelA_results))
if modelB_used == 'used':
modelB_results = modelB.objects.filter(modelB__icontains=search_query).only('modelMain')
queryset = queryset.union(modelMain.objects.filter(modelB__in=modelB_results))
if modelC_used == 'used':
modelC_results = modelC.objects.filter(value__icontains=search_query)
queryset = queryset.union(modelMain.objects.filter(modelC__in=modelC).distinct())
return queryset