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
Вернуться на верх