2016-12-09 2 views
1

In einer Django-Anwendung habe ich eine Reihe von Unternehmen mit einer Historie von Aktionen, die in der Vergangenheit durchgeführt wurden. Ich abrufen diese Transaktionen mit dem folgenden, skandalös teuer Queryset:Wie kann dieses spezifische Queryset optimiert werden?

class Company(AbstractBaseUser, PermissionsMixin): 
    ... 
    def get_transactions_history(self): 
     return Transaction.objects.filter(sponsorship__campaign__shop__company=self) 

Offensichtlich führt dies zu viel JOIN Anweisungen von den ORM und da die Anzahl der Transactions schnell erhöhen kann, der Durchsatz auf der db auch explodiert wegen dieses Querysets.

Angenommen, es gibt keine Abkürzung zwischen Transaction und Company andere als Sponsorship durch Verkettungs, Campaign und Shop wie oben ausgesetzt, wie würden Sie die Queryset ohne Berührung an das Datenbankschema zu optimieren?

+0

Wenn das Endergebnis der Transaktion - Unternehmensbeziehung ist wie ein "Passthrough", mit einem "Trigger" eine Schattenkopie von nur "transaction_id" und "company_id" erstellen, wenn eine Transaktion erstellt wird, scheint mir logisch – Anzel

+0

Das einzige etwas, das einer Optimierung nahekommt, wäre 'shop__company_id = self.id', aber ich glaube nicht, dass das viel helfen würde. – Sayse

+0

@Sayse wie würde' company_id = self.id' die Leistung verbessern? Liegt der Vergleich von zwei ganzen Zahlen schneller als der Vergleich zweier Objekte? – Buddyshot

Antwort

1

Ich glaube nicht, dass Sie wirklich können, aber Sie können schlauer sein, wie Sie es verwenden.

Theres cached_property

@cached_property 
def history(self): 

Welche genau das tut, was sie sagt, es ist.

Andernfalls müssen Sie diese in eine recent_history spalten, die die queryset

.filter(...)[:10] 

oder Paginierung Spleißstellen

0

Wenn Sie es nicht auf SQL-Ebene optimieren können dann gibt es nicht viel können Sie auf das tun ORM-Level, offensichtlich.

Verwandte Themen