Frage

So habe ich baut django-Anwendungen für eine Weile jetzt, und die kühle Hilfe und alle trinken: nur die ORM und nie benutzerdefinierte SQL schreiben

.

Die Hauptseite der Website (die primäre Schnittstelle, wo Benutzer 80% verbringen - 90% ihrer Zeit) war immer langsam, wenn Sie eine große Menge an benutzerspezifischen Inhalte (dh Fotos, Freunde, andere Daten, usw.)

Also habe ich in dem SQL-Logger knallte (war vorinstalliert mit Pinax, ich aktivierte es einfach in den Einstellungen) und stellen Sie sich meine Überraschung, als er berichtete über 500 Datenbankabfragen !! Mit Hand codierte SQL kaum lief ich immer mehr als 50 auf den komplexesten Seiten.

Im Nachhinein ist es nicht alle zusammen überraschend, aber es scheint, dass dies nicht gut sein kann.

... wenn auch nur ein Dutzend oder so die Abfragen 1ms nehmen +

Also ich frage mich, , wie viel Aufwand ist es auf einer Rundreise zu mysql ? django und MySQL sind auf der Seite demselben Server läuft , so gibt es keine Vernetzung bezogenen Gemein sein sollte.

War es hilfreich?

Lösung

Es gibt einige Möglichkeiten, um die Abfrage Volumen zu reduzieren.

  1. Mit .filter() und .all() ein paar Dinge zu bekommen; Pick und in der View-Funktion (oder eine Vorlage über {%if%}) wählen. Python kann eine Charge von Zeilen schneller als MySQL verarbeiten.

    „Aber ich konnte zu viel auf die Vorlage senden“. Das stimmt, aber Sie werden weniger SQL-Anfragen ausführen. Messen, um zu sehen, welche besser ist.

    Dies ist, was Sie zu tun pflegen, wenn Sie SQL geschrieben. Es ist nicht falsch - es ist nicht das ORM bricht -. Aber es optimiert die zugrunde liegende DB Arbeit und setzt die Verarbeitung in die View-Funktion und die Vorlage

  2. Vermeiden Sie Abfrage Navigation in der Vorlage. Wenn Sie das tun {{foo.bar.baz.quux}}, SQL verwendet wird, um die bar mit foo verbunden zu bekommen, dann ist die baz mit dem bar verbunden ist, dann ist die quux mit baz verbunden. Sie können diese Abfrage Geschäft mit einigen sorgfältigen .filter() und Python Verarbeitung zu reduzieren Lage sein, eine nützliche Tupel in der View-Funktion zu montieren.

    Auch dies war etwas, was Sie zu tun pflegte, wenn Sie SQL Hand gefertigt. In diesem Fall sammeln Sie größere Chargen von ORM-verwalteten Objekten in der View-Funktion und machen Sie Ihre Filterung in Python statt über viele einzelne ORM-Anfragen.

    Dieses bricht nicht die ORM. Es ändert sich das Nutzungsprofil von vielen kleinen Anfragen an einigen größeren Abfragen.

Andere Tipps

Nur weil Sie ein ORM verwenden, bedeutet nicht, dass Sie nicht die Leistungsoptimierung tun sollten.

Ich hatte - wie Sie - eine Homepage eines meiner Anwendungen, die geringe Leistung hatte. Ich sah, dass ich Hunderte von Abfragen zu tun, die Seite anzuzeigen. Ich ging in meinem Code suchen und erkannte, dass mit einigen sorgfältige Verwendung von select_related() meine Fragen mehr der Daten bringen würde ich brauchte -. Ich ging von Hunderten von Anfragen an zig

Sie können auch eine SQL Profiler und sehen laufen, wenn es keine Indizes sind, die Ihre häufigsten Fragen helfen würde - wissen Sie, Standard-Datenbank Zeug

.

Caching ist auch dein Freund, würde ich denken. Wenn eine Menge einer Seite nicht ändern, tun Sie die Datenbank jedes Mal abfragen müssen?

Wenn alles andere fehlschlägt, denken Sie daran: die ORM ist groß, und ja - Sie sollten versuchen, es zu benutzen, weil es die Django Philosophie ist; , aber sie sind nicht auf sie verheiratet .

Wenn Sie wirklich eine usecase haben, wo das Studium und die ORM-Navigation Tuning nicht helfen, wenn Sie sicher sind, dass Sie es viel besser mit einer Standardabfrage tun könnten. Verwenden raw SQL für diesen Fall

Der Aufwand der einzelnen Abfragen ist nur ein Teil des Bildes. Die tatsächliche Umlaufzeit zwischen Django und Mysql-Server ist wahrscheinlich sehr klein, da die meisten Ihrer Fragen kommen zurück in weniger als einer Millisekunde. Das größere Problem ist, dass die Anzahl der Anfragen an die Datenbank ausgegeben es schnell überwältigen können. 500 Abfragen für eine Seite ist viel zu viel, sogar 50 wie viel mir scheint. Wenn zehn Benutzer komplizierte Seiten anzeigen Sie sind jetzt bis zu 5000 Abfragen.

Die Umlaufzeit auf dem Datenbankserver mehr ein Faktor ist, wenn der Anrufer die Datenbank von einem Wide Area Network zugreifen, wo Rundreisen leicht zwischen 20 ms und 100 ms sein kann.

Ich würde auf jeden Fall schauen Sie in eine Art von Caching verwenden.

Es gibt immer Overhead in der Datenbank Anrufen, in Ihrem Fall der Aufwand ist nicht , dass schlecht, weil die Anwendung und die Datenbank ist auf der gleiche Maschine, so dass keine Netzwerklatenz, aber es ist immer noch ein erheblich Kosten .

Wenn Sie machen eine Anfrage an die Datenbank darauf vorbereiten muss, dass die Anforderung zu bedienen, indem Sie eine Reihe von Dingen zu tun, einschließlich:

  • Zuweisung von Ressourcen (Speicherpuffer, temporäre Tabellen usw.) auf die Datenbank-Server-Verbindung / Thread, der die Anforderung wird handhaben,
  • De-Serialisierung der SQL und Parameter (dies erforderlich ist, auch auf einer Maschine, da dies eine Inter-Prozess-Anfrage, wenn Sie eine eingebettete Datenbank verwenden)
  • Überprüfen, ob die Abfrage im Abfrage-Cache vorhanden ist, wenn es nicht optimieren und sie in der Cache gestellt.
    • Beachten Sie, dass auch dann, wenn Ihre Fragen nicht parametrisiert (dh die Werte werden nicht von der SQL getrennt) dies in Cache-Misses für Aussagen führen können, dass die gleiche Bedeutung sein sollte, dass jede Anfrage Ergebnisse in der Abfrage analysiert und optimiert jede Zeit.
  • Prozess der Abfrage aus.
  • Vorbereitung und die Ergebnisse an den Client zurück.

Dies ist nur ein Überblick über die Arten von Dingen, die meisten Datenbank-Management-Systeme tun, um eine SQL-Anfrage zu bearbeiten. Sie entstehen diese Overhead-500-mal, auch wenn die die Abfrage selbst relativ schnell läuft. Unterm Strich Datenbank-Interaktionen sogar zu lokaler Datenbank sind nicht so billig, wie man erwarten könnte.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top