sql >> Databáze >  >> RDS >> PostgreSQL

Proč je tento počet anotací Django (1.6) tak pomalý?

Proč je pomalý :Pokud jste jednoduše použili anotaci dvěma poli ManyToMany pak vytvoříte nechtěné velké spojení všech těchto tabulek spolu. Velikost kartézského součinu řádků, které je třeba vyhodnotit, je přibližně Have.objects.count() * Want.objects.count() . Pak jste napsali distinct=True konečně omezit počet duplicitních položek, aby nedošlo k neplatnému obrovskému výsledku.

Oprava starého Djanga:Pokud byste použili pouze queryset.annotate(have_count=Count("have")) správný výsledek získáte rychle bez distinct=True nebo stejný výsledek také rychle s výrazným. Potom můžete zkombinovat výsledky dvou dotazů Pythonu v paměti.

Řešení Pěkné řešení je možné v Django>=1.11 (dva roky po vaší otázce) pomocí dotazu s dva poddotazy , jeden pro Have a jeden pro Want , vše na základě jednoho požadavku, ale ne smíchat všechny tabulky dohromady.

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

Ověřit :Pomalý i pevný SQL dotaz můžete zkontrolovat vytištěním str(my_queryset.query) že je to tak, jak je popsáno výše.




  1. 3 způsoby, jak vypsat všechny uložené procedury, které odkazují na tabulku v PostgreSQL

  2. Jak poskytnout heslo pro PostgreSQL createdb neinteraktivně?

  3. MySQL Workbench

  4. Je v MySQL dostupný příkaz merge