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.
quelle
Antworten:
Ich könnte in diesem Fall blind fliegen, aber hier geht es ...
In Ihrer Frage und Ihren Kommentaren haben Sie Folgendes angegeben:
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.
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 ?
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.
quelle