sql >> Database teknologi >  >> RDS >> PostgreSQL

Hvorfor er denne Django (1.6) annotattælling så langsom?

Hvorfor er det langsomt :Hvis du blot brugte annotationen med to ManyToMany-felter så opretter du en uønsket stor sammenføjning af alle disse tabeller sammen. Størrelsen af ​​det kartesiske produkt af rækker, der skal evalueres, er ca. Have.objects.count() * Want.objects.count() . Du skrev derefter distinct=True for endelig at begrænse antallet af duplikerede elementer for ikke at få et ugyldigt enormt resultat.

Rette til gammel Django:Hvis du kun ville bruge queryset.annotate(have_count=Count("have")) du får hurtigt det rigtige resultat uden distinct=True eller det samme resultat også hurtigt med distinkt. Derefter kan du kombinere resultaterne af to forespørgsler fra Python i hukommelsen.

Løsning En god løsning er mulig i Django>=1.11 (to år efter dit spørgsmål) ved at bruge en forespørgsel med to underforespørgsler , en for Have og en for Want , alt efter én anmodning, men ikke for at blande alle tabeller sammen.

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))

Bekræft :Du kan kontrollere både den langsomme og den faste SQL-forespørgsel ved at udskrive str(my_queryset.query) at det er som beskrevet ovenfor.




  1. Hvilken OJDBC-driver til Java 6?

  2. MySQL Foreign Key Constraint - Heltalskolonne

  3. Tilføjelse af et INDEX til en CTE

  4. Hvordan ændrer jeg en PostgreSQL-tabel og gør en kolonne unik?