2016-02-02 15 views
6

Es gibt zwei Modelle mit einer Eins-zu-viele-Beziehung, A -> {B}. Ich zähle, wie viele Datensätze von A ich mit dem gleichen B habe, nachdem ich einen Filter benutzt habe(). Dann muss ich die obersten X Datensätze von A in Bezug auf die meisten B Datensätze, die mit ihnen verbunden sind, extrahieren.Django: Alternative zur Verwendung von Annotate (Count()) für Geschwindigkeit

Der aktuelle Code:

class A(models.Model): 
    code = models.IntegerField() 
    ... 

class B(models.Model): 
    a = models.ForeignKey(A) 
    ... 

data = B.objects.all().filter(...) 

top = data.values('a',...).annotate(n=Count('a')).distinct().order_by('-n')[:X]; 

Ich habe ~ 300k B Aufzeichnungen und mit meinem Laptop dies nimmt ~ 2s für eine Abfrage. Ich sezierte die Anfrage in Teile und zeitlich abgestimmt und es scheint der größte Engpass ist der Kommentar().

Gibt es irgendeinen Weg, dies schneller mit Django zu tun?

Antwort

0

Sie sollten .select_related('a') vor annotate im Abfrage-Set hinzufügen. Dies wird den Django dazu zwingen, sich den Modellen anzuschließen, bevor sie gezählt werden.

https://docs.djangoproject.com/en/1.9/ref/models/querysets/#select-related

+0

Wenn ich das tun, bevor die Werte() Aufruf (archivierte), die Zeit, in etwa gleich bleibt. Oder meinst du ich muss dies vor dem Filter tun() und dann wird eine Gruppe von Anrufen schneller? – user1581390

+0

Haben Sie versucht, das SQL mit 'print (data.sql)' zu betrachten? – onlythefinestwilldo

Verwandte Themen