You: "I get the SQL with queryset.explain(analyze=True, buffers=True) or from pg_stat_statements.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # ====================================================================== # Q: CTO: "A report query takes 12 seconds. Show me how you approach it." # # You: "I get the SQL with queryset.explain(analyze=True, buffers=True) or from # pg_stat_statements. I look for a seq scan on a large table, a big gap between # estimated and actual rows, and a sort that spills to disk. Usually the fix is # a composite index with the equality column first, partial if we always filter # by status. I build the index CONCURRENTLY. If the report doesn't need fresh # data, I send it to the read replica or to a materialized view refreshed by # Celery." # ====================================================================== qs = (Order.objects.filter(company_id=cid, status='paid', created_at__gte=since) .values('created_at__date').annotate(total=Sum('total'))) print(qs.explain(analyze=True, buffers=True)) class Meta: indexes = [models.Index( fields=['company', 'created_at'], include=['total'], condition=Q(status='paid'), name='order_paid_company_created')] |