Как повысить производительность Django ORM при запросах с использованием prefetch_related? (задействовано много различных таблиц)

У меня есть модель Django, которая связана со многими другими моделями в обратных отношениях ForeignKey, то есть многие-к-одному.

Иллюстрация:

class ModelA:
    photo_url = URLField(null=True)


class AbstractModel:
    class Meta:
        abstract = True

    modelA_ref = ForeignKey(to=ModelA, on_delete=dj_models.CASCADE)


class ModelB(AbstractModel):
    whatever = TextField(null=True)


class ModelC(AbstractModel):
    whatever = TextField(null=True)


class ModelD(AbstractModel):
    whatever = TextField(null=True)

и так далее еще десятки раз.

У меня есть сериализатор для ModelA, и соответствующее представление для вызова соответствующей конечной точки /api/v1/modela/<uuid:key>/ в Django REST Framework.

Иллюстрация:

from rest_framework.generics import RetrieveAPIView


class ModelASerializer:
    modelb_field = ListSerializer(source="modelb_set", child=ModelBSerializer())
    modelc_field = ListSerializer(source="modelc_set", child=ModelCSerializer())
    modeld_field = ListSerializer(source="modeld_set", child=ModelDSerializer())


class ModelAView(RetrieveAPIView):
    serializer_class = ModelASerializer
    lookup_field = "id"
    lookup_url_kwarg = "key"

    def get_queryset(self):
        key = self.kwargs["key"]

        return ModelA.objects.filter(id=key).prefetch_related(
            'modelb_set', 'modelc_set', 'modeld_set'
        )

Конечно, эта оптимизация не мешает Django запрашивать все различные таблицы при достижении конечной точки /api/v1/modela/<uuid:key>/, как и ожидалось: в моей ситуации накопление запросов занимает 60% времени отклика в 1000 мс, что слишком долго.

Отсюда мой вопрос: является ли рефакторинг схемы моей базы данных, чтобы эти модели поместились в одну единственную таблицу, единственным вариантом? Или есть что-то более элегантное, что можно сделать?

Спасибо за ваше время.

Вернуться на верх