Ich arbeite an einer Anwendung, die viele Datenbankschreibvorgänge, ungefähr 70% Einfügungen und 30% Lesevorgänge umfasst. Dieses Verhältnis würde auch Aktualisierungen einschließen, die ich als ein Lese- und ein Schreibvorgang betrachte. Durch Einfügeanweisungen fügen mehrere Clients Daten über die folgende Einfügeanweisung in die Datenbank ein:
$mysqli->prepare("INSERT INTO `track` (user, uniq_name, ad_name, ad_delay_time ) values (?, ?, ?, ?)");
Die Frage ist, ob ich entweder insert_delay oder mysqli_multi_query verwenden soll , da die insert-Anweisung auf dem Server ~ 100% CPU verwendet. Ich verwende die InnoDB-Engine in meiner Datenbank, sodass ein verzögertes Einfügen nicht möglich ist. Das Einfügen auf dem Server ist ~ 36k / h und 99,89% gelesen. Außerdem verwende ich die select-Anweisung, um dort sieben Mal Daten in einer einzelnen Abfrage abzurufen . Die Ausführung dieser Abfrage auf dem Server dauert 150 Sekunden. Welche Technik oder welchen Mechanismus kann ich für diese Aufgabe verwenden? Mein Serverspeicher ist 2 GB, sollte ich Speicher erweitern?. Schauen Sie sich dieses Problem an, jeder Vorschlag wird mir dankbar sein.
Tabellenstruktur:
+-----------------+--------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+-------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user | varchar(100) | NO | | NULL | |
| uniq_name | varchar(200) | NO | | NULL | |
| ad_name | varchar(200) | NO | | NULL | |
| ad_delay_time | int(11) | NO | | NULL | |
| track_time | timestamp | NO | MUL | CURRENT_TIMESTAMP | |
+-----------------+--------------+------+-----+-------------------+----------------+
Mein Datenbank-Status zeigt 41.000 Einfügungen (Schreibvorgänge) an, was für meine Datenbank sehr langsam ist.
SHOW FULL PROCESSLIST
wenn es 100% CPU nimmt? Wie viele Verbindungen erlauben Sie und wie viele werden in dieser Zeit genommen?SHOW GLOBAL VARIABLES LIKE 'innodb%';
undSELECT VERSION();
und zeigen Sie ihre Ausgabe an.Antworten:
Da Sie mehr Schreibvorgänge als Lesevorgänge haben, möchte ich Folgendes empfehlen
Eine anständige Abstimmung von InnoDB wäre der Schlüssel
Pufferpool ( Größe von innodb_buffer_pool_size )
Da InnoDB INSERT DELAYED nicht unterstützt , ist die Verwendung eines großen InnoDB- Pufferpools am nächsten an INSERT DELAYED. Alle DML (INSERTs, UPDATEs und DELETEs) werden im InnoDB-Pufferpool zwischengespeichert. Transaktionsinformationen für die Schreibvorgänge werden sofort in die Redo-Protokolle (ib_logfile0, ib_logfile1) geschrieben. Die im Pufferpool veröffentlichten Schreibvorgänge werden regelmäßig über ibdata1 (InsertBuffer für Sekundärindizes, Double Write Buffer) vom Speicher auf die Festplatte geleert. Je größer der Pufferpool ist, desto mehr INSERTs können zwischengespeichert werden. Verwenden Sie in einem System mit 8 GB oder mehr RAM 75-80% des RAM als innodb_buffer_pool_size. In einem System mit sehr wenig RAM 25% (um das Betriebssystem aufzunehmen).
CAVEAT: Sie können innodb_doublewrite auf 0 setzen, um das Schreiben noch weiter zu beschleunigen, jedoch mit dem Risiko der Datenintegrität. Sie können die Arbeit auch beschleunigen, indem Sie innodb_flush_method auf O_DIRECT setzen, um zu verhindern, dass InnoDB an das Betriebssystem zwischengespeichert wird.
Protokolle wiederholen ( Größe von innodb_log_file_size )
Standardmäßig heißen die Redo-Protokolle ib_logfile0 und ib_logfile1 und betragen jeweils 5 MB. Die Größe sollte 25% der Größe innodb_buffer_pool_size betragen. Wenn die Redo-Protokolle bereits vorhanden sind, fügen Sie die neue Einstellung in my.cnf hinzu, fahren Sie mysql herunter, löschen Sie sie und starten Sie mysql neu .
Protokollpuffer ( Größe von innodb_log_buffer_size )
Der Protokollpuffer enthält Änderungen im RAM, bevor sie in die Redo-Protokolle übertragen werden. Der Standardwert ist 8M. Je größer der Protokollpuffer ist, desto weniger Festplatten-E / A. Seien Sie vorsichtig bei sehr großen Transaktionen, da dies COMMITs um Millisekunden verlangsamen kann.
Zugriff auf mehrere CPUs
MySQL 5.5 und das MySQL 5.1 InnoDB-Plugin verfügen über Einstellungen, mit denen InnoDB Storage Engine auf mehrere CPUs zugreifen kann. Hier sind die Optionen, die Sie einstellen müssen:
Upgrade auf MySQL 5.5
Wenn Sie über MySQL 5.0 verfügen, aktualisieren Sie auf MySQL 5.5. Wenn Sie MySQL 5.1.37 oder früher haben, aktualisieren Sie auf MySQL 5.5. Wenn Sie MySQL 5.1.38 oder höher haben und in MySQL 5.1 bleiben möchten, installieren Sie das InnoDB-Plugin. Auf diese Weise können Sie alle CPUs für InnoDB nutzen.
quelle
INT (2) verwendet immer noch 4 Bytes - vielleicht meinten Sie TINYINT UNSIGNED?
Wie viele verschiedene Werte in setno? Wenn es klein ist, wird der SCHLÜSSEL (setno) niemals verwendet. INSERTing muss diesen Index aktualisieren. Durch Entfernen des Schlüssels wird INSERT etwas beschleunigt.
CHAR (10) - Ist
flag
immer 10 Zeichen lang? Und in utf8? Vielleicht könnten Sie das Flag VARCHAR (10) CHARACTER SET ascii verwendenStapeln Sie Ihre Beilagen - 100 auf einmal laufen zehnmal so schnell. (Über 100 steigt die Rendite.)
Was ist der Wert von Autocommit? Wickeln Sie jedes INSERT in BEGIN ... COMMIT ein? Was ist der Wert von innodb_flush_log_at_trx_commit?
quelle
code
eingefügt werden? Ist es zuverlässig, wenn ich Folgendes verwende: Einfügen in t_name (col1, col2, col3) Werte (val1, val2, val3), (val1, val2, val3), (val1, val2, val3), (val1, val2, val3), (val1, val2, val3);code
Richten Sie eine Warteschlange ein. Die Anwendung schreibt jeweils 1 Zeile in eine Warteschlange und nimmt dann Zeilen heraus und fügt sie stapelweise in eine Datenbank ein, basierend auf der Anzahl der Zeilen, die seit dem letzten Einfügen vergangen sind.
Ich habe gesehen, wo das Stapeln der Einsätze 10.000 auf einmal am schnellsten ist, also müssten Sie testen, um einen Sweet Spot zu finden.
Sie können Ihr eigenes einfaches Warteschlangensystem erstellen oder ein vorhandenes verwenden. Hier einige Beispiele: HornetQ und File :: Queue . Hier ist ein Beitrag auf SE, in dem einige andere gute Optionen aufgelistet sind: Nachrichtenwarteschlangen in Perl, PHP, Python .
quelle