join_buffer_size> = 4 M wird nicht empfohlen?

9

Ich erhalte diese Nachricht von MysqlTunner.pl:

join_buffer_size> = 4 M Dies wird nicht empfohlen

Andererseits habe ich in Debians my.cnf-Handbuch über jont_buffer_size gelesen, dass:

Dieser Puffer wird zur Optimierung vollständiger JOINs (JOINs ohne Indizes) verwendet. Solche JOINs sind in den meisten Fällen ohnehin sehr schlecht für die Leistung, aber wenn Sie diese Variable auf einen großen Wert setzen, werden die Auswirkungen auf die Leistung verringert. In der Statusvariablen "Select_full_join" finden Sie eine Anzahl der vollständigen JOINs. Wird pro Thread zugewiesen, wenn eine vollständige Verknüpfung gefunden wird

Also frage ich mich, welchem ​​ich glauben soll? Derzeit habe ich join_buffer_size = 64M festgelegt, um das Skalierbarkeitsproblem einer Site mit hohem Datenverkehr zu bewältigen, deren Abfragen nicht besonders optimiert sind. Ich schätze Ihre Hinweise dazu.

Alfish
quelle
Ich habe meine Antwort mit einem Abschnitt über die Geschwindigkeit des Speicherzugriffs aktualisiert.
Maxim Masiutin

Antworten:

6

join_buffer_size = 64 MB sind irgendwie verrückt, das sind + 64 MB, die jedem neuen Thread zugewiesen werden.

Die Größe des Puffers, der für einfache Index-Scans, Bereichsindex-Scans und Joins verwendet wird, die keine Indizes verwenden und daher vollständige Tabellenscans durchführen. Normalerweise ist der beste Weg, um schnelle Verknüpfungen zu erhalten, das Hinzufügen von Indizes. Erhöhen Sie den Wert von join_buffer_size, um einen schnelleren vollständigen Join zu erhalten, wenn das Hinzufügen von Indizes nicht möglich ist.

Ich würde sagen, Sie sollten join_buffer_sizeauf einen Wert zwischen 128Kund reduzieren , 256Kwährend Sie Indizes zu Ihren Tabellen hinzufügen und den soeben gespeicherten Speicher verwenden, um key_buffer_size> + 10x zu erhöhen .

Mehr Speicher übersetzen nicht immer zu mehr Geschwindigkeit, allgemeine Beispiele: sort_buffer_size, read_buffer_size, read_rnd_buffer_sizeund table_open_cache. Google es.

Alix Axel
quelle
1
> join_buffer_size = 64 MB sind irgendwie verrückt, das sind + 64 MB, die jedem neuen Thread zugewiesen wurden. Eigentlich ist das nicht ganz richtig. Die Größe des Verknüpfungspuffers wird NICHT jedem Thread zugewiesen. Es wird nur bei JEDER vollständigen Tabellenverknüpfung zugewiesen. Wenn also ein vollständiger Tabellen-Join ausgeführt wird, weist mysql die Datei "join_buffer_size" zu. Beachten Sie außerdem, dass mysql "join_buffer_size" für jede verknüpfte Tabelle zuweist, wenn Sie mehrere Tabellen ohne Indizes in derselben Abfrage (demselben Thread) verknüpfen. Abgesehen davon stimme ich den Kommentaren von Alix Axels zu.
5

Beide scheinen mir dasselbe zu sagen. Sie sagen dir beide, dass FULL JOINS SCHLECHT sind .

  • Mysqltuner weist darauf hin, dass etwas an Ihrem System schlecht ist. In diesem Fall ist ein großer Join-Puffer ein Zeichen dafür, dass Sie etwas Schlechtes an Ihrer Datenbank haben.
  • Die Dokumentation sagt Ihnen, dass es schlecht ist, aber wenn Sie Ihren Code nicht ändern können, können Sie durch Hinzufügen von mehr Speicher die Fehler akzeptieren.

Haben Sie die Select_full_joinVariable überprüft ? Sehen Sie tatsächlich diesen Zähleranstieg? Sind Sie sicher, dass das Reparieren des Codes oder das Anschreien der für das Reparieren Verantwortlichen keine Option ist?

Zoredache
quelle
Nun, select_full_join = 0. Im Moment kann ich den Code nicht reparieren oder jemanden anschreien. Meine beste Wette ist es also, die bestmögliche Leistung aus MySQL herauszuholen. Danke
Alfish
4

Erhöhen Sie nicht die Puffer pro Verbindung!

Nicht alle Puffer in my.cnf werden nur einmal für die Serverinstanz zugewiesen. Für jede Verbindung sind einige Puffer zugeordnet. Weitere Informationen finden Sie unter https://haydenjames.io/my-cnf-tuning-avoid-this-common-pitfall/ :

Zitat:

Puffer wie join_buffer_size, sort_buffer_size, read_buffer_size und read_rnd_buffer_size werden pro Verbindung zugewiesen. Daher fordert eine Einstellung von read_buffer_size = 1M und max_connections = 150 MySQL auf, vom Start an 1 MB pro Verbindung x 150 Verbindungen zuzuweisen. Seit mehr als einem Jahrzehnt bleibt der Standardwert bei 128 KB. Das Erhöhen der Standardeinstellung ist nicht nur eine Verschwendung von Serverspeicher, sondern trägt häufig nicht zur Leistungssteigerung bei. In fast allen Fällen ist es am besten, die Standardeinstellungen zu verwenden, indem diese vier Pufferkonfigurationszeilen entfernt oder auskommentiert werden. Reduzieren Sie sie für einen schrittweisen Ansatz um die Hälfte, um verschwendeten Arbeitsspeicher freizugeben, und reduzieren Sie sie im Laufe der Zeit weiter auf Standardwerte. Ich habe tatsächlich einen verbesserten Durchsatz durch Reduzieren dieser Puffer gesehen. Aber es gibt wirklich keine Leistungssteigerungen durch das Erhöhen dieser Puffer, außer in Fällen von sehr hohem Datenverkehr und / oder anderen besonderen Umständen. Vermeiden Sie es, diese willkürlich zu erhöhen!

Die Geschwindigkeit des Speicherzugriffs

Im Gegensatz zur üblichen Logik ist der Zugriff auf den Speicher nicht O (1).

Je mehr RAM Sie haben, desto langsamer ist der Zugriff auf alle Daten in diesem RAM.

Die Verwendung von weniger RAM kann also tatsächlich einen schnelleren Zugriff auf den RAM ermöglichen - dies ist eine allgemeine Regel, die nicht nur für MySQL gilt. Bitte lesen Sie The Myth of RAM - warum ein zufälliger gelesener Speicher O (√N) ist

Kehren wir nun zu MySQL join_buffer_size zurück.

Optimieren von MySQL join_buffer_size

Die join_buffer_size wird für jeden vollständigen Join zwischen zwei Tabellen zugewiesen. In der MySQL-Dokumentation wird join_buffer_size wie folgt beschrieben: "Die Mindestgröße des Puffers, der für einfache Index-Scans, Bereichsindex-Scans und Joins verwendet wird, die keine Indizes verwenden und daher vollständige Tabellenscans durchführen." Weiter heißt es: "Die Speicherzuweisungszeit kann zu erheblichen Leistungseinbußen führen, wenn die globale Größe größer ist als von den meisten Abfragen, die sie verwenden, benötigt wird." Der Join-Puffer wird Cache-Tabellenzeilen zugewiesen, wenn der Join keinen Index verwenden kann. Wenn Ihre Datenbank (en) unter vielen Verknüpfungen leiden, die ohne Indizes ausgeführt werden, kann dies nicht durch einfaches Erhöhen von join_buffer_size gelöst werden. Das Problem ist "Verknüpfungen ohne Indizes". Daher besteht die Lösung für schnellere Verknüpfungen darin, Indizes hinzuzufügen.

Ändern Sie die MySQL-Konfiguration so, dass Abfragen ohne Indizes protokolliert werden, sodass Sie solche Abfragen finden und Indizes hinzufügen und / oder die Anwendung ändern können, die solche fehlerhaften Abfragen generiert. Sie sollten "Protokollabfragen, die keine Indizes verwenden" aktivieren. Suchen Sie dann im Protokoll für langsame Abfragen nach nicht indizierten Verknüpfungen.

Maxim Masiutin
quelle
0

Das glaube ich nicht. Es ist wahrscheinlich, dass mysqltuner Ihnen eine Konfiguration vorschlägt, die auf der Konfiguration basiert, die Sie möglicherweise benötigen. wenn ich mysqltuner auf einem DB-Server ausführe. Hier ist es eine Empfehlung, die ich bekomme:

Variables to adjust:
  *** MySQL's maximum memory usage is dangerously high ***
  *** Add RAM before increasing MySQL buffer variables ***
    join_buffer_size (> 64.0M, or always use indexes with joins)
    innodb_buffer_pool_size (>= 54G) if possible.
    innodb_log_file_size should be (=2G) if possible, so InnoDB total log files size equals to 25% of buffer pool size.

Ich denke, es ist nicht immer eine schlechte Größe auf einem anderen Server und braucht.

Yuda Prawira
quelle
0

JOINS ohne INDEXES sollten durch Analyse und entsprechende Indexerstellung aufgelöst werden.

Verwenden Sie mysqlcalculator.com mit Ihrer join_buffer_size, um die Auswirkungen auf den Speicherbedarf zu sehen. Sollte weniger als 1 Minute Ihrer Zeit für ein dramatisches Ergebnis dauern.

Wilson Hauck
quelle