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