Хобрук: Ваш путь к мастерству в программировании

Платформа отдыха Django ModelSerializer работает слишком медленно

Мы хотим предоставить API для нашего проекта django, поэтому мы используем drf (django rest framework). мы используем ModelSerializer, который предоставляет ярлык, позволяющий автоматически создавать класс Serializer с полями, соответствующими полям модели. Наша проблема в том, что он работает очень медленно. Другими словами, процесс сериализации занимает около 40 секунд до получения ответа.

Как мы можем уменьшить эту задержку?
VIEW

class MyObjViewSet(viewsets.ModelViewSet):

    pagination_class = LargeResultsSetPagination

    def get_queryset(self):
        queryset = MyObj.objects.all().order_by('time')
        return queryset

    serializer_class = MyObjSerializer

Моя модель объекта

class MyObj(models.Model):
    id = models.BigIntegerField(primary_key=True)
    time = models.DateTimeField()
    type = models.CharField(max_length=5)
    user = models.ForeignKey('User', related_name='myobj')

Пользовательская модель MyObj

class User(models.Model):
    id = models.IntegerField(primary_key=True)
    username = models.CharField(max_length=80)

мой сериализатор Obj

class MyObjSerializer(serializers.ModelSerializer):

    class Meta:
        model = MyObj
        fields = ('id', 'type', 'time', 'user')

Моя проблема в том, что когда я хочу получить список своих объектов, это занимает около 40 секунд!


  • Возможный дубликат Оптимизация запросов к базе данных в Django Rest Framework 28.01.2016
  • @KevinBrown: Нет, это не моя проблема! 28.01.2016
  • Уверены ли вы? Это кажется очень похожим (внешний ключ с другой моделью), это также объясняется здесь ses4j.github.io/2015/11/23/ 28.01.2016
  • Я все еще приветствую новые ответы на этот вопрос, я считаю, что сериализаторы Django медленные. :/ И это не проблема БД. 09.02.2018

Ответы:


1

На самом деле, это настоящая проблема drf.
Если у вас есть много объектов, возвращаемых queryset, вам нужно сделать несколько шагов:
1. Убедитесь, что вы используете many=True, это приведет к значительному повышению производительности.< br> 2. Избегайте ModelSerializer на больших наборах объектов. На самом деле стоит избегать любых rest_framework.Serializer
3. Попробуйте использовать serpy библиотеку для сериализации. Но не стоит забывать, что он не полностью совместим с rest_framework.Serializer.
4. Используйте .values() и DictSerializer. Это значительно ускорит сериализацию.
5. Не забывайте об индексах в вашей базе данных. 6. Используйте такие мощные вещи, как prefetch_related и select_related, работая с ForeignKey.
7. Последний способ - использовать простой dict. В остальном ощутимого результата я не получил: всего 10% против serpy с DictSerializer.

У меня был случай, когда мне нужно сериализовать много объектов (около 3-5к), накладные расходы на сериализатор drf составили не менее 2,5 секунд (без учета времени sql). После оптимизации я получил примерно ~ 200-300 мс.

Я надеюсь, что разработчики drf сделают некоторые улучшения производительности во фреймворке.

31.10.2018

2

Проблема не в сериализаторе, проблема в запросе.

Вы получаете все объекты, я предполагаю, что их большое количество из-за нумерации страниц, а также вы хотите, чтобы они были упорядочены по времени. Проблема в том, что в определении модели нет подсказки для базы данных, чтобы создать индекс для поля времени.

Попробуйте добавить подсказку для создания индекса в базе данных и скорость возрастет.

  class MyObj(models.Model):
      id = models.BigIntegerField(primary_key=True)
      time = models.DateTimeField(db_index=True)
      type = models.CharField(max_length=5)
      user = models.ForeignKey('User', related_name='myobj')
26.01.2016
  • Спасибо, я сделал это, но проблема все еще существует! 27.01.2016
  • Взгляните на этот stackoverflow.com/questions/26109184/ о миграциях, но, как вы говорите, время запроса выглядит нормально, поэтому у меня нет подсказок 27.01.2016
  • Время запроса нормальное! Я предполагаю, что моя проблема связана с логикой DRF, а не с базой данных. но я не могу найти решение. я имею в виду, что процесс поиска и получения набора запросов важен... 28.01.2016

  • 3

    Чувак, не используй "MyObj.objects.all().order_by('time')",

    Если у вас есть более десятков сотен данных, то просто получите все и упорядочите по времени, это займет так много времени......

    «это не проблема сериализатора, это проблема порядка». вы можете ограничить время поиска, используйте:

    1、gt:больше чем

    now = datetime.datetime.now()
    #yesterday
    start = now – datetime.timedelta(hours=23, minutes=59, seconds=59)
    a=yourobject.objects .filter(youdatetimcolumn__gt=start)
    

    2、gte: больше или равно

    a=yourobject.objects .filter(youdatetimcolumn__gte=start)
    

    3、lt:немного тогда

    a=yourobject.objects .filter(youdatetimcolumn__lt=start)
    

    4、lte: меньше или равно

    a=yourobject.objects .filter(youdatetimcolumn__lte=start)
    

    5, диапазон: диапазон времени

    start_date = datetime.date(2005, 1, 1)
    end_date = datetime.date(2005, 3, 31)
    Entry.objects.filter(pub_date__range=(start_date, end_date))
    

    6, год: один из лет

    Entry.objects.filter(pub_date__year=2005)
    

    7, месяц: один из месяцев

    Entry.objects.filter(pub_date__month=12)
    

    8, день: в день

    Entry.objects.filter(pub_date__day=3)
    

    9、week_day:день недели

    Entry.objects.filter(pub_date__week_day=2)
    

    источник: https://www.cnblogs.com/linjiqin/p/3821914.html< /а>

    Если вам нужно использовать get.all, то просто не используйте "order_by_time", в обычной ситуации не используйте order_by_time, это может ускорить ваш запрос, вам просто нужно заказать его после получения этих данных.

    01.02.2019
    Новые материалы

    Как симулировать серию пенальти на Python с помощью симуляции Монте-Карло, часть 1: генерация функций
    Серия пенальти была огромным испытанием во время чемпионата мира по футболу. Они вызвали много споров в социальных сетях и новостных агентствах. Даже финальный матч турнира решался по..

    AST для разработчиков JavaScript
    TL; DR Эта статья - мое выступление на недавно состоявшейся конференции Stockholm ReactJS Meetup. Вы можете посмотреть слайды здесь..

    5 проектов на Python, которые нужно создать прямо сейчас!
    Добро пожаловать! Python — один из моих любимых языков программирования. Если вы новичок в этом языке, перейдите по ссылке ниже, чтобы узнать о нем больше:

    Dall-E 2: недавние исследования показывают недостатки в искусстве, созданном искусственным интеллектом
    DALL-E 2 — это всеобщее внимание в индустрии искусственного интеллекта. Люди в списке ожидания пытаются заполучить продукт. Что это означает для развития креативной индустрии? О применении ИИ в..

    «Очень простой» эволюционный подход к обучению с подкреплением
    В прошлом семестре я посетил лекцию по обучению с подкреплением (RL) в моем университете. Честно говоря, я присоединился к нему официально, но я редко ходил на лекции, потому что в целом я нахожу..

    Освоение информационного поиска: создание интеллектуальных поисковых систем (глава 1)
    Глава 1. Поиск по ключевым словам: основы информационного поиска Справочная глава: «Оценка моделей поиска информации: подробное руководство по показателям производительности » Глава 1: «Поиск..

    Фишинг — Упаковано и зашифровано
    Будучи старшим ИТ-специалистом в небольшой фирме, я могу делать много разных вещей. Одна из этих вещей: специалист по кибербезопасности. Мне нравится это делать, потому что в настоящее время я..