Wie kann die Leistung von MySQL INSERT und UPDATE verbessert werden?


14

Diese Frage kann wahrscheinlich auch auf StackOverflow gestellt werden, aber ich werde es hier zuerst versuchen ...

Die Leistung von INSERT- und UPDATE-Anweisungen in unserer Datenbank scheint sich zu verschlechtern und die Leistung unserer Web-App zu beeinträchtigen.

Tabellen sind InnoDB und die Anwendung verwendet Transaktionen. Gibt es einfache Verbesserungen, die ich vornehmen kann, um die Dinge zu beschleunigen?

Ich glaube, wir haben einige Probleme mit Sperren. Wie kann ich das herausfinden?


Besser bei dba.stackexchange.com
Pacerier

Antworten:


25
  1. Überprüfen Sie, ob Ihre Hardware und Ihr Betriebssystem richtig konfiguriert und optimiert sind:

    • Problemursache (CPU / IO / Memory / Swap Usage). Hast du viele IOPs? Ist die CPU geladen? Wenn Sie viele IOPs gelesen haben, haben Sie wahrscheinlich nicht genug großen InnoDB-Pufferpool. Wenn die CPU geladen ist, führen Ihre Abfragen wahrscheinlich vollständige Tabellensuchen durch, anstatt die richtigen Indizes zu verwenden.
    • Festplatten- / RAID- / LVM-Setup. In einigen spezifischen Konfigurationen können Sie durch LVM-Striping die Festplattenlast ausgleichen (kein Hardware-RAID, mehrere LUNs verbunden).
    • IO-Scheduler: Wenn Sie einen guten Hardware-RAID-Controller haben, ist wahrscheinlich noop der beste. RedHat machte einige Tests und sie sagten, dass für Oracle (und andere DB) CFQ die beste Wahl ist. Sie müssen einige Benchmarks (wie tpc-c oder tpc-e) ausführen und auswählen, was für Ihre Hardware am besten ist.
    • Gutes Dateisystem - ext3 funktioniert bei datenbankspezifischen Workloads nicht gut. Besser ist XFS oder OCFS2. Sie brauchen wieder einige Benchmarks.
    • Beobachten Sie, ob Ihr System Swap verwendet. Die Verwendung von Swap verschlechtert die Leistung von MySQL .
  2. Überprüfen Sie, ob Ihre MySQL / InnoDB-Instanz richtig eingestellt ist:

    • Pufferpoolgröße - Cache-Datenseiten im Speicher
    • innodb_flush_method = O_DIRECT - Doppelte E / A-Pufferung vermeiden
    • Erhöhen Sie die Größe der InnoDB-Protokolldatei. Bei einer schreibintensiven Arbeitslast kann dies die Leistung verbessern. Denken Sie jedoch daran: Eine größere Protokolldatei bedeutet eine längere Wiederherstellung nach einem Absturz. Manchmal in Stunden !!!
    • innodb_flush_log_at_trx_commit = 0 oder 2 - Wenn Sie sich keine Gedanken über ACID machen und Transaktionen für die letzte oder zweite Sekunde verlieren können.
    • key_buffer_size - sehr wichtig für MyISAM, wird jedoch für temporäre Festplattentabellen verwendet.
    • Beobachten Sie Ihren INNODB-STATUS
  3. Analysieren Sie Ihre Arbeitslast - fangen Sie alle Ihre Abfragen im Slowquery-Protokoll ab und führen Sie mk-query-digest darauf aus. Sie können alle Abfragen mit tcpdump und maatkit abfangen
    • Welche Abfragen beanspruchen die meiste Zeit Ihres Servers?
    • Werden temporäre Tabellen erstellt, insbesondere große temporäre Tabellen?
    • Lerne, wie man EXPLAIN benutzt
    • Verwendet Ihre Anwendung Transaktionen? Wenn Sie Abfragen mit autocommit = 1 ausführen (standardmäßig MySQL), beginnt jede Einfüge- / Aktualisierungsabfrage mit einer neuen Transaktion, die einen gewissen Aufwand verursacht. Wenn es möglich ist, sollten Sie die automatische Festschreibung deaktivieren (in Python ist die automatische Festschreibung für MySQL-Treiber standardmäßig deaktiviert) und die Festschreibung manuell ausführen, nachdem alle Änderungen vorgenommen wurden.
    • Fügt Ihre Anwendung in einer Schleife mehrere Einfügungen in dieselbe Tabelle ein? Load data infileBefehl ist viel schneller für Serien von Einfügungen.
    • Denken Sie daran: select count(*) from table;ist für Innodb viel langsamer als für Myisam.
    • Welche Arten von INSERT / UPDATE-Abfragen benötigen die meiste Serverzeit? Wie können sie optimiert werden?
    • Überprüfen Sie, ob Ihre Datenbank über geeignete Indizes verfügt, und fügen Sie diese bei Bedarf hinzu.

In unserer Umgebung hatten wir die Situation, dass eine Art von Aktualisierungsabfragen langsam war. Die geschätzte Zeit bis zum Abschluss des Batch-Auftrags betrug 2 Tage !!! Nach der Analyse des Slowquery-Protokolls stellen wir fest, dass diese Art der Aktualisierungsabfrage 4 Sekunden benötigt, um abgeschlossen zu werden. Abfrage sah wie folgt aus : update table1 set field1=value1 where table1.field2=xx table2.field3=yy and table2.field4=zz. Nach dem Konvertieren der Aktualisierungsabfrage in eine Auswahlabfrage und dem Ausführen von EXPLAIN für diese Auswahlabfrage stellen wir fest, dass dieser Abfragetyp keinen Index verwendet. Nachdem wir den richtigen Index erstellt hatten, konnten wir die Ausführungszeit für Aktualisierungsabfragen auf Millisekunden reduzieren und den gesamten Auftrag in weniger als zwei Stunden erledigen.

Einige nützliche Links:


5

Mit der Standardkonfiguration von innoDB können Sie nur Transaktionen schreiben und auf die Festplatte übertragen. Wenn Sie ein wenig ACID verlieren können, experimentieren Sie mit innodb_flush_log_at_trx_commit. Setzen Sie den Wert auf 0, um das Protokoll etwa jede Sekunde auf die Festplatte zu schreiben und zu löschen. Auf 1 (Standard) setzen, um bei jedem Commit zu schreiben und zu leeren. Auf 2 setzen, um nach jedem Commit in die Protokolldatei zu schreiben, aber nur einmal pro Sekunde zu leeren.

Wenn Sie mit dem Verlust von 1s von Transaktionen umgehen können, kann dies eine großartige Möglichkeit sein, die Schreibleistung erheblich zu verbessern.

Achten Sie auch darauf, was Ihre Festplatten tun. RAID 10> RAID 5 für Schreibvorgänge auf Kosten einer zusätzlichen Festplatte.


1

Sperrprobleme werden anhand des Verbindungsstatus in angezeigt show full processlist;

Lesen Sie die my.cnfund MySQL-Dokumentation. Konfigurationsmöglichkeiten sind sehr gut dokumentiert.

Im Allgemeinen möchten Sie so viel wie möglich im Speicher verarbeiten. Für die Abfrageoptimierung bedeutet dies, dass temporäre Tabellen vermieden werden. Richtige Anwendung von Indizes.

Die Optimierung richtet sich nach Ihrer bevorzugten Datenbank-Engine und Anwendungsarchitektur. Es gibt erhebliche Ressourcen, die eine Internetsuche bereits entfernt haben.



0

InnoDB ist ein ziemlich guter Motor. Es hängt jedoch stark davon ab, „gestimmt“ zu sein. Eine Sache ist, dass innoDB etwas länger dauern kann als MyISAM, wenn sich Ihre Einfügungen nicht in der Reihenfolge zunehmender Primärschlüssel befinden. Dies kann leicht überwunden werden, indem eine höhere innodb_buffer_pool_size festgelegt wird. Mein Vorschlag ist, es auf 60-70% Ihres gesamten RAM festzulegen. Ich betreibe derzeit 4 solcher Server in der Produktion und füge ungefähr 3,5 Millionen Zeilen pro Minute ein. Sie haben bereits fast 3 Terabyte. InnoDB musste es sein, wegen der hochkonkurrierenden Inserts. Es gibt weitere Möglichkeiten, um Einfügungen zu beschleunigen. Und ich habe einige verglichen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.