I am having issues with the performance of a couple of queries in my Django app... all others are very fast.
I have an Orders model with OrderItems, the query seems to be running much slower than other queries (1-2 seconds, vs. 0.2 seconds). I'm using MySQL backend. In the serializer I do a count to return whether an order has food or drink items, I suspect this is causing the performance hit. Is there a better way to do it?
Here is my models setup for Order and OrderItems
class Order(models.Model):
  STATUS = (
       ('1', 'Placed'),
       ('2', 'Complete')
   )
   PAYMENT_STATUS = (
       ('1', 'Pending'),
       ('2', 'Paid'),
       ('3', 'Declined'),
       ('4', 'Manual')
   )
   shop= models.ForeignKey(Shop,on_delete=models.DO_NOTHING)
   customer = models.ForeignKey(Customer,on_delete=models.DO_NOTHING)
   total_price = models.DecimalField(max_digits=6, decimal_places=2,default=0)
   created_at = models.DateTimeField(auto_now_add=True, null=True)
   time_completed = models.DateTimeField(auto_now_add=True, null=True,blank=True)
   time_cancelled = models.DateTimeField(auto_now_add=True, null=True,blank=True)
   status = models.CharField(max_length=2, choices=STATUS, default='1',)
   payment_method =  models.CharField(max_length=2, choices=PAYMENT_METHOD, default='3',)
   payment_status =  models.CharField(max_length=2, choices=PAYMENT_STATUS, default='1',)
   type =  models.CharField(max_length=2, choices=TYPE, default='1',)
   def __str__(self):
       return str(self.id)
class OrderItem(models.Model):
   order = models.ForeignKey(Order,on_delete=models.CASCADE)
   type = models.CharField(max_length=200,default='DRINK')
   drink = models.ForeignKey(
       Drink,
       blank=True,null=True,on_delete=models.DO_NOTHING
   )
   food = models.ForeignKey(
       Food,
       blank=True,
       null=True,
        on_delete=models.DO_NOTHING
   )
   quantity = models.IntegerField(blank=True,null=True)
   price = models.DecimalField(max_digits=6, decimal_places=2,default=0)
   created_at = models.DateTimeField(auto_now_add=True, null=True)
   delivered = models.BooleanField(default=False)
   def __str__(self):
       return str(self.id)
In my rest order serializer, here is the query for get,
queryset = Order.objects.filter(shop=shop,status__in=['1','2'],payment_status__in=['2','4'])
The serializer is below, but this query is quite slow. I assume because I am doing a count() on OrderItems - is there a more efficient way to do this?
class OrderOverviewSerializer(serializers.ModelSerializer):
   tabledetails = serializers.SerializerMethodField()
   has_food = serializers.SerializerMethodField()
   has_drink = serializers.SerializerMethodField()
   class Meta:
       model = Order
       fields = ['id','total_price', 'created_at','has_food','has_drink','type','status','shop','table','customer','shopdetails']
   def get_shopdetails(self, instance):
       qs = Shop.objects.get(id=instance.shop.id)
       serializer = ShopSerializer(instance=qs, many=False)
       return serializer.data
   def get_has_food(self, obj):
       foodCount = OrderItem.objects.filter(order=obj.id,type='FOOD').count()
       return foodCount
   def get_has_drink(self, obj):
       drinkCount = OrderItem.objects.filter(order=obj.id,type='DRINK').count()
       return drinkCount
 
     
     
     
    