Riesige Leistungsunterschiede von MySQL auf zwei Servern

8

Wir haben einen MySQL-Server auf zwei verschiedenen Computern installiert, einen Testserver und einen Produktionsserver, beide Fenster, die von einer Webanwendung verwendet werden.

Das Problem ist, dass es bei der Ausführung einiger Abfragen RIESIGE Leistungsunterschiede zwischen den beiden Computern gibt (der Produktionsserver ist der langsamere). Die MySQL-Version auf beiden Servern ist identisch, auch die Konfigurationsdateien sind identisch (der einzige Unterschied ist der Pfad der Daten und die Tatsache, dass der Produktionsserver nur die Fehler protokolliert). Der Leistungsunterschied, von dem ich spreche, ist 3 oder 4 Größenordnungen größer (z. B. wird eine Abfrage auf dem Testserver in 0,2 s ausgeführt, während sie auf dem Produktionsserver in 84 s ausgeführt wird).

Die beleidigenden Abfragen verwenden in großem Umfang Klauseln mit "WHERE [...] IN [...]". Meines Wissens sind sie normalerweise sehr langsam und sollten durch JOINs ersetzt werden. Die von uns verwendete Version von MySQL ist jedoch 5.6.19, wodurch diese Abfragen automatisch optimiert werden. Deshalb arbeiten sie auf dem Testserver schnell (und sie befinden sich in einem Teil des Programms, den wir nicht ändern können, sodass wir sie nicht manuell optimieren können wie auch immer).

Wie gesagt, die Installation und Konfiguration von MySQL sind identisch, sodass ich keine Ahnung habe, wo das Problem liegen könnte. Einerseits vermute ich, dass es sich um ein Konfigurationsproblem handeln muss, da das Programm und die Datenbank identisch sind. Andererseits ist dies nicht sinnvoll, da die Konfiguration identisch ist.

Einige Daten auf den Servern:
Testserver:

  • Intel Core 2 Quad Q9400 bei 2,66 GHz
  • 8 GB RAM
  • Windows Server 2008 R2 Standard

Produktionsserver:

  • Intel Xeon E5530 bei 2,40 GHz
  • 5 GB RAM
  • Windows Server 2012 R2 Standard

Bearbeiten: Ich habe vergessen, eine wichtige Sache zu sagen: Es werden mehr Abfragen ausgeführt, die "WHERE ... IN" -Klauseln für die "beleidigenden" verwenden. Sie werden auf beiden Maschinen schnell ausgeführt, was darauf hindeutet, dass sie von MySQL korrekt optimiert werden. Die Tatsache, dass einige Abfragen optimiert werden, während andere nicht optimiert werden, ist mir ein Rätsel, WENN dies das eigentliche Problem ist, bei dem ich mir nicht sicher bin.

Edit # 2: Hier ist die Konfigurationsdatei für beide Server: http://pastebin.ca/2834906

Edit # 3: Hier ist die EXPLAIN einer der langsamen Abfragen: https://mariadb.org/ea/v36zj Die EXPLAIN ist in Test und Produkt genau gleich. Die Abfrage selbst ist hier: http://pastebin.com/VXgBxXmt Sie wurde mit einem Autoformatter formatiert, ist also möglicherweise nicht sehr klar. Wie Sie sehen können, ist ziemlich lang und komplex. Es wird nicht von Hand generiert, sondern automatisch von der Software generiert, die mit einigen Funktionen einen Dialekt des Standard-SQL verwendet.

Weitere Informationen: Wir haben das Problem vorübergehend behoben, indem wir die Daten auf dem Produktionsserver reduziert und die meisten alten Daten in der Datenbank entfernt haben, die nicht verwendet werden sollen. Dies ist natürlich keine Lösung, da wir auch die alten Daten benötigen und dies in Zukunft ein Problem sein wird. Die Datenbank ist nicht so groß: Die vollständige Datenbank ist 1308 MB groß, die derzeit in Produktion befindliche reduzierte Version ist 332 MB groß.

UPDATE: Gelöst?

Ich glaube, ich habe das Problem gelöst. Ich habe es noch nicht getestet, da der Produktionsserver tatsächlich verwendet wird, aber das mögliche Problem war der Parameter "innodb_buffer_pool_size", der auf 182 MB festgelegt wurde. Tatsächlich zeigt die Zeile in der Konfigurationsdatei: innodb_buffer_pool_size = 321, was ein Fehler ist, da es nicht das Einheitenpräfix hat, einen ungültigen Wert angibt (das Minimum ist 5242880 gemäß den Dokumenten) und ihn dann auf den vorherigen Wert setzt . Dieser Wert im Testserver wurde auf die gewünschten 321 MB eingestellt.

Wie gesagt, ich habe es nicht vollständig getestet. Was ich getan habe, ist, den Wert beim Testen zu reduzieren und die Anwendung zu testen. Alles läuft langsamer und die von mir gepostete Abfrage wird in 3 Minuten ausgeführt.

Ich habe einen vernünftigeren Wert von 3 GB getestet, von dem ich nicht weiß, ob es eine gute Idee ist. Wenn also jemand einen Kommentar zu diesem Wert hat, werde ich ihn zu schätzen wissen.

Meine Schlussfolgerungen, der "vernünftige Wert" von 3 GB und die Informationen, die ich dafür verwendet habe, stammen aus diesen beiden Beiträgen, insbesondere dem zweiten:

MySQL-Abfrage, 2 ähnliche Server, 2 Minuten Unterschied in den Ausführungszeiten

Wie groß sollte mysql innodb_buffer_pool_size sein?

Ich werde die "echten" Ergebnisse veröffentlichen, wenn wir die Werte auf dem Produktionsserver aktualisieren.

Danke an alle.

Gelöst

Also haben wir dies endlich in prod getestet und es war das Problem, das ich zuvor kommentiert habe. Ich habe den Wert von innodb_buffer_pool_size in 321M angegeben. Dies ist der Wert, der vom Hersteller des von uns verwendeten SDK empfohlen wird, obwohl er gemäß den vorherigen Links für eine Datenbank dieser Größe und Verwendung etwa 3 G betragen sollte.

Ich habe jedoch immer noch Zweifel: Der Wert von 321 war ein ungültiger Wert (zu klein), daher hat MySQL einen anderen Wert angenommen. Mein Verdacht ist, dass es die vorher gültige Nummer genommen hat, 321M im Test und 182M im Produkt, daher die Geschwindigkeitsunterschiede. Es ist nur aus Neugier, aber ich würde gerne wissen, ob das richtig ist.

Nochmals vielen Dank für die Hilfe.

Juantxorena
quelle
1
Sind die Datenbanken auf jedem Server gleich groß? Eine kleinere Testdatenbank wird schneller ausgeführt als eine größere Produktionsdatenbank. Außerdem verfügt der Testserver über fast das Doppelte des Arbeitsspeichers. Wie sieht die Speichernutzung aus?
1
Ja, die Datenbank ist dieselbe (tatsächlich ein Speicherauszug der Produktionsdatenbank in die Testdatenbank). Ich habe die Speichernutzung auf dem Produktionsserver noch nicht überprüft, werde ich jetzt informieren.
1
Könnten Sie die gleichen RAM-Statistiken aus der Testbox ziehen? Sehen Sie, ob sie deutlich anders aussehen?
Chris S
2
Können Sie ein Beispiel für eine Abfrage veröffentlichen, die in TEST hervorragend ausgeführt wird, in PROD jedoch schrecklich ist? Führen Sie außerdem den EXPLAIN-Plan für die Abfrage in beiden Systemen aus und veröffentlichen Sie die Ergebnisse.
RolandoMySQLDBA
3
@juantxorena: Sie müssen Gründe verwerfen und nichts annehmen , von leicht bis schwer zu überprüfen. Schritt 1 Grund: Unterschiede im Abfrageplan. Führen Sie EXPLAIN in der Produktion und in der Entwicklung aus und prüfen Sie, ob Unterschiede bestehen (auch wenn diese minimal sind). Fügen Sie diese Informationen hinzu und dann können wir mit Schritt 2
fortfahren

Antworten:

4

Ich könnte in diesem Fall blind fliegen, aber hier geht es ...

In Ihrer Frage und Ihren Kommentaren haben Sie Folgendes angegeben:

Die MySQL-Version auf beiden Servern ist identisch, auch die Konfigurationsdateien sind identisch (der einzige Unterschied ist der Pfad der Daten und die Tatsache, dass der Produktionsserver nur die Fehler protokolliert).

Ja, die Datenbank ist dieselbe (tatsächlich ein Speicherauszug der Produktionsdatenbank in die Testdatenbank).

Ähnliche Ergebnisse: 2,31 GB auf stabile Weise

Sie sollten den EXPLAIN-Plan für eine Abfrage bereitstellen. Da die Daten identisch sind, ist dies möglicherweise nicht erforderlich.

Es gibt einige Dinge, die unterschiedlich sein können

IHR PROZESSOR

Ich habe den Intel Core 2 Quad Q9400 bei 2,66 GHz (TEST) und den Intel Xeon E5530 bei 2,40 GHz (PROD) nachgeschlagen und einen Unterschied festgestellt.

  • CPU für TEST hat 4 Threads
  • CPU für PROD hat 8 Threads

Sie würden denken, PROD sollte schneller sein.

Die interne Busgeschwindigkeit kann der Engpass sein. Ich würde dies vermuten, da TEST eine höhere Busgeschwindigkeit und einen Busmultiplikator von 8 hat. Was ist ein Busmultiplikator ?

Die interne Frequenz von Mikroprozessoren basiert normalerweise auf der Frequenz des Front-Side-Busses. Zur Berechnung der internen Frequenz multipliziert die CPU die Busfrequenz mit einer bestimmten Zahl, die als Taktvervielfacher bezeichnet wird. Es ist wichtig zu beachten, dass die CPU für die Berechnung die tatsächliche Busfrequenz und nicht die effektive Busfrequenz verwendet. Um die tatsächliche tatsächliche Busfrequenz für Prozessoren zu bestimmen, die Busse mit zwei Datenraten (AMD Athlon und Duron) und Busse mit vier Datenraten (alle Intel-Mikroprozessoren ab Pentium 4) verwenden, sollte die effektive Busgeschwindigkeit durch 2 für AMD oder 4 für geteilt werden Intel.

Basierend darauf ist die interne Busgeschwindigkeit für AMD (TEST) mindestens doppelt so hoch wie für Intel (PROD).

IHRE INDEX-STATISTIKEN

Da Sie TEST mit denselben Daten geladen haben, wurde möglicherweise eines übersehen. Ich denke an die Indexstatistik. Für TEST wäre die Indexstatistik ziemlich neu. Bei PROD kann es veraltet sein, wenn in den indizierten Tabellen viele INSERTs, UPDATEs und DELETEs aufgetreten sind.

Das Ausführen eines SELECT auf zwei verschiedenen Computern mit identischer MySQL-Version, identischen MySQL-Konfigurationen, identischen Datasets und sogar identischer Hardware kann durch Indexstatistiken für die betreffende Tabelle beeinflusst werden.

Ich würde ANALYZE TABLE für alle Tabellen in PROD und TEST ausführen und dann versuchen, die Leistung zu vergleichen.

RolandoMySQLDBA
quelle
Vielen Dank für Ihre gründliche Antwort. Ich habe die ANALYSETABELLE für alle Tabellen durchgeführt, und die Ausführungszeiten sind ähnlich. PROD ist in den meisten Fällen etwas langsamer, in anderen etwas schneller, aber ich spreche von Millisekunden, daher denke ich nicht, dass dies die Ursache ist. Ich gucke immer noch.
Juantxorena