Как оптимизировать пакетный запрос, чтобы сделать его быстрее

При изменении статуса документа я хотел бы перевести все продукты в документе на склад. Для этого нужно изменить несколько полей. При небольшом количестве экземпляров товара запрос работает быстро >50ms. Однако в некоторых документах есть товары в количестве, например, 3000. Такой запрос занимает более секунды. Я знаю, что будут случаи с гораздо большим количеством экземпляров. Я бы хотел, чтобы запрос выполнялся быстрее.

Простой цикл занимает ~1 секунду.

class PZ_U_Serializer(serializers.ModelSerializer):
    class Meta:
        model = PZ
        fields = '__all__'

    def update(self, instance, validated_data):
        items = instance.pzitem_set.all()
        bulk_update_list = []
        for item in items:
            item.quantity = 100
            item.quantity_available_for_sale = 100
            item.price = 100
            item.available_for_sale = True
            item.save()
        return super().update(instance, validated_data)

Batch_update занимает около 400 мс на поле. В данном случае 1600мс (что медленнее, чем цикл).

class PZ_U_Serializer(serializers.ModelSerializer):
    class Meta:
        model = PZ
        fields = '__all__'

    def update(self, instance, validated_data):
        items = instance.pzitem_set.all()
        bulk_update_list = []
        for item in items:
            item.quantity = 100
            item.quantity_available_for_sale = 100
            item.price = 100
            item.available_for_sale = True
            bulk_update_list.append(item)
        items.bulk_update(bulk_update_list, ['quantity', 'price', 'quantity_available_for_sale', 'available_for_sale'], batch_size=1000)
        return super().update(instance, validated_data)

В консоли post-gre я вижу на (3000 объектов) около 11 000 обращений на чтение. Я пробовал добавить transaction.atomic перед циклом, но это ничего не изменило (если я все сделал правильно).

Вы пытались использовать метод queryset update()?
Это избавит вас от множества запросов на обновление и выполнения циклов :

    def update(self, instance, validated_data):
        instance.pzitem_set.all().update(
            quantity = 100, 
            quantity_available_for_sale = 100,
            price = 100,
            available_for_sale = True,
        )
        return super().update(instance, validated_data)

Больше информации в официальном документе здесь.

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