MySQL ist bei sehr einfachen SELECT-Abfragen extrem langsam


10

Wir haben eine einfache Webanwendung, die auf einer virtuellen Maschine ausgeführt wird, die ihre Daten in einer MySQL 5.5-Datenbank mit der InnoDB-Engine speichert. Etwa drei Jahre lang hat alles gut funktioniert, aber plötzlich wurde es extrem langsam.

Zum Beispiel habe ich eine sehr einfache Tabelle mit Adressen:

CREATE TABLE `addresses` (
  `address_id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(64) CHARACTER SET latin1 NOT NULL,
  `firstname` varchar(64) CHARACTER SET latin1 NOT NULL,
  `street` varchar(64) CHARACTER SET latin1 NOT NULL,
  `housenumber` varchar(16) CHARACTER SET latin1 NOT NULL,
  `zip` varchar(5) CHARACTER SET latin1 NOT NULL,
  `city` varchar(64) CHARACTER SET latin1 NOT NULL,
  `email` varchar(64) CHARACTER SET latin1 NOT NULL,
  `phone` varchar(16) CHARACTER SET latin1 NOT NULL,
  `birthdate` date NOT NULL,
  PRIMARY KEY (`address_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin

Diese Tabelle enthält ungefähr 800 Einträge, was wirklich nicht viel ist. Aber die Abfrage ausführen

SELECT * FROM addresses

zu Testzwecken scheint es nie zu Ende zu sein. Ich habe dies mit der MySQL-CLI auf dem Server selbst überprüft: Sie gibt einige Zeilen der Tabelle aus und wartet dann sehr lange, bis die nächsten Zeilen ausgegeben werden.

Vielleicht ist es ein Problem in der Datenversandphase, aber ich bin mir nicht sicher.

Die VM verfügt über 2 GB RAM und es werden nur 320 MB verwendet. Die CPU läuft auch mit sehr niedrigen 1 bis 2%. mytop zeigt keine anderen Abfragen an, die den Server blockieren. Der IT-Administrator sagte, dass er auf der Hardwareseite nichts geändert habe.

Ich habe bereits versucht, den Datenbankserver neu zu starten und die virtuelle Maschine neu zu starten. Nichts hat geholfen.

bearbeiten:

EXPLAIN SELECT * FROM addresses

gibt mir dieses Ergebnis:

+----+-------------+-----------+------+---------------+------+---------+------+------+-------+
| id | select_type | table     | type | possible_keys | key  | key_len | ref  | rows | Extra |
+----+-------------+-----------+------+---------------+------+---------+------+------+-------+
|  1 | SIMPLE      | addresses | ALL  | NULL          | NULL | NULL    | NULL |  793 |       |
+----+-------------+-----------+------+---------------+------+---------+------+------+-------+
1 row in set (0.00 sec)

Virtual Box, Xen oder etwas anderes? Wie ist die Host-Festplatte eingerichtet? Gibt es andere VMs auf derselben Box, die ebenfalls langsam laufen? Die Beantwortung dieser Fragen könnte die Antwort enthüllen
Matt

Ich bin nicht der Besitzer des Hypervisors, daher kann ich dies nicht wirklich beantworten. Ich habe den Administrator des Hypervisors bereits gefragt, ob er von den letzten Änderungen weiß, aber er hat nein gesagt.
Tab

Wenn Sie können, fahren Sie MySQL herunter und führen Sie einen Festplatten- und Speicher-Benchmark aus. Muss nicht kompliziert sein. Die Idee ist, nur zu isolieren, ob es sich um ein Problem mit MySQL handelt, möglicherweise um ein Indexproblem, wie in der Antwort unten angegeben, oder um ein weit verbreitetes.
Matt

Guter Punkt, ich habe es als wahrscheinlich kein MySQL-Problem erlebt. Das Ausführen mysql -u username -ppassword mydb -e 'SELECT * FROM addresseswird langsam ausgegeben, aber das Anhängen von `> test.txt` wird sehr schnell ausgeführt. Nun wäre das wahrscheinlich eine andere Frage!? Wie könnte ich das untersuchen?
Tab

Wenden Sie sich an den Eigentümer des Hypervisors und bitten Sie ihn, die Protokolle auf Fehler zu überprüfen. Insbesondere Festplattenfehler. Sagen Sie ihm Ihre Symptome. Jetzt sichern.
Matt

Antworten:


13

Wenn die CPU-Auslastung niedrig ist, gibt dies an, dass es keine Probleme mit fehlenden Indizes gibt. In diesem Fall müsste die Abfrage nur mehr CPU- und Festplattenzugriff benötigen. Sie sagten auch, dass es 3 Jahre lang gut funktioniert hat.

Haben Sie die allgemeine Datenträgerzugriffsgeschwindigkeit überprüft (insbesondere auf der Partition, auf der sich die Datenbank befindet)? ZB dd wie hier verwenden . Was Sie beschreiben, klingt wie eine tote Festplatte oder ein halbtoter Überfall. Hast du Backups, hoffe ich?


Das ist ein guter Punkt. Es könnte so einfach sein wie ein Festplattenfehler auf dem Host.
Matt

9

Sie können ein paar Dinge ausprobieren,

  1. Haben Sie Indizes eingerichtet?

Durch die Indizierung können Datensätze schnell gefunden werden, ohne zuvor einen vollständigen Tabellenscan durchzuführen. Dadurch werden die Ausführungszeiten erheblich verkürzt.

CREATE INDEX idx_name ON addresses(name);
  1. Verwenden Sie vor dem Ausführen der Abfrage zuerst das Schlüsselwort EXPLAIN.

Bei Verwendung vor einer SELECT-Abfrage wird beschrieben, wie MySQL die Abfrage ausführen möchte und wie viele Zeilen verarbeitet werden müssen, bevor sie abgeschlossen ist.

  1. Nehmen Sie einige Änderungen an Ihrer mysql.ini vor, wenn es sich um eine VM handelt, die den RAM erhöht, und konfigurieren Sie Ihre mysql.ini, um festzustellen, ob sich die Leistung erhöht.

Es gibt viele MySQL-Optimierer, die Sie führen können.

Hilfe das hilft


Okay, aber das Erstellen eines Index für eine recht kleine Tabelle (<800 Zeilen) scheint nicht so hilfreich zu sein, wie ich es brauchen würde. Es dauert über eine Minute, bis die oben angegebene Abfrage abgeschlossen ist. Ein vollständiger Tabellenscan eines so kleinen Tisches sollte nicht so lange dauern.
Tab

Also ... haben Sie die Indizes hinzugefügt? Wenn Sie sich nicht sicher sind, wo das Problem liegt, würde ich einfach anfangen und mich nach unten arbeiten. Das Hinzufügen von Indizes erhöht die Leistung nur, wenn dies korrekt durchgeführt wird.
Anthony Fornito

Ja, ich habe einen Index für die Namensspalte hinzugefügt. Meine obige Abfrage enthält jedoch nicht einmal eine einschränkende WHERE-Klausel, sodass die gesamte Tabelle gelesen und ausgedruckt werden muss. Der Index hat nicht geholfen.
Tab

Ich habe das Ergebnis der obigen EXPLAIN-Abfrage hinzugefügt. Das sieht für mich gut aus, aber die Leistung ist immer noch sehr gering. Ich kann den Arbeitsspeicher nicht erhöhen, da ich nicht der Administrator des Virtualisierungsmanagers bin. htopZeigt aber , dass nur 307MB von 2050MB RAM verwendet werden.
Tab

Über Indizes müssen Sie wirklich darüber nachdenken, welche Spalten indiziert werden sollen. Sie möchten nicht einfach alles indizieren, sondern diejenigen mit der größten Menge indizieren. Ich mache einige wilde Annahmen, aber ich würde mit nameund 'Vorname' beginnen. Zweitens sind Sie sicher, dass Sie die Indizierung korrekt durchgeführt haben? Möglich_Tasten: NULL Wenn die Spalte NULL ist, bedeutet dies, dass keine relevanten Indizes gefunden wurden.
Anthony Fornito
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.