Как повысить производительность 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 мс, что слишком долго.
Отсюда мой вопрос: является ли рефакторинг схемы моей базы данных, чтобы эти модели поместились в одну единственную таблицу, единственным вариантом? Или есть что-то более элегантное, что можно сделать?
Спасибо за ваше время.