sql >> Databasteknik >  >> RDS >> PostgreSQL

Varför är denna Django (1.6) annotering så långsam?

Varför det går långsamt :Om du helt enkelt använde kommentaren med två ManyToMany-fält sedan skapar du en oönskad stor sammanfogning av alla dessa tabeller tillsammans. Storleken på den kartesiska produkten av rader som måste utvärderas är ungefär Have.objects.count() * Want.objects.count() . Du skrev då distinct=True för att slutligen begränsa antalet dubblerade objekt för att inte få ett ogiltigt enormt resultat.

Fix för gamla Django:Om du bara skulle använda queryset.annotate(have_count=Count("have")) du får rätt resultat snabbt utan distinct=True eller samma resultat också snabbt med distinkt. Sedan kan du kombinera resultaten av två frågor från Python i minnet.

Lösning En bra lösning är möjlig i Django>=1.11 (två år efter din fråga) genom att använda en fråga med två underfrågor , en för Have och en för Want , allt efter en begäran, men inte för att blanda alla tabeller tillsammans.

from django.db.models import Count, OuterRef, Subquery

sq = Collection.objects.filter(pk=OuterRef('pk')).order_by()
have_count_subq = sq.values('have').annotate(have_count=Count('have')).values('have_count')
want_count_subq = sq.values('want').annotate(have_count=Count('want')).values('want_count')
queryset = queryset.annotate(have_count=Subquery(have_count_subq),
                             want_count=Subquery(want_count_subq))

Verifiera :Du kan kontrollera både den långsamma och den fasta SQL-frågan genom att skriva ut str(my_queryset.query) att det är som beskrivits ovan.




  1. Oracle dokumentation

  2. De där jäkla stora föremålen

  3. Mysqldump:skapa kolumnnamn för infogningar vid säkerhetskopiering

  4. Med MySQL, hur kan jag generera en kolumn som innehåller postindexet i en tabell?