Ich bin ein Programmierer, kein DBA. Sei sanft :)
Überblick
- InnoDB, MySQL
- mod_perl Skript, dauerhafte Verbindungen
- Skript, das alle 20 Sekunden von Tausenden von Benutzern aufgerufen wird
Problem
- High Disk IO (vermutlich verursacht durch Updates [?]) Verlangsamt alles und führt zu einem großen Engpass.
Abfragen
- UPDATE [einzelne Tabelle] SET refreshTime auf den aktuellen Zeitstempel setzen, mit zwei gleichen Tabellenprüfungen in der WHERE-Klausel
- SELECT COUNT (*) [vier Tabellenverknüpfungen mit Indizes] und eine Reihe von ANDs in der WHERE-Klausel (immer noch ziemlich einfach)
- SELECT a, b [vier Tabellenverknüpfungen, dieselben vier Tabellen] und eine Reihe von UNDs in der WHERE-Klausel (ebenfalls ziemlich einfach)
Der Abfragecache ist aktiviert.
Lösungen?
- Ich bin kein DBA, aber ich vermute, dass es möglich ist, eine Tabelle im RAM zu haben, die regelmäßig (alle 10 Sekunden?) Auf die Festplatte aktualisiert wird und im Falle eines katastrophalen Fehlers die RAM-Tabelle automatisch aus der Festplattentabelle auffüllt beim Neustart, aber ich habe keine Ahnung, ob es tatsächlich möglich ist, ob es die beste Lösung ist oder welche anderen Optionen es gibt.
- Irgendwelche Gedanken oder Vorschläge? Auch hier bin ich Programmierer. Wenn also jemand jemanden kennt, der dies gegen eine Gebühr tut, oder mich auf ganz bestimmte Ressourcen verweisen kann, wäre ich sehr dankbar.
~~~~~~~~
CREATE TABLE `openInvitations` (
`id` int(99) NOT NULL auto_increment,
`createTime` timestamp NULL default NULL,
`repAcceptTime` timestamp NULL default NULL,
`rep_id` varchar(64) NOT NULL default '',
`repRefreshTime` timestamp NULL default NULL,
`customer_macAddr` varchar(14) NOT NULL default '',
`customerRefreshTime` timestamp NULL default NULL,
`stage` char(1) NOT NULL default 'P',
`parent` varchar(25) default NULL,
`reason` varchar(64) default NULL,
PRIMARY KEY (`rep_id`,`customer_macAddr`),
UNIQUE KEY `id` (`id`),
KEY `customer_macAddr` (`customer_macAddr`),
CONSTRAINT `openInvitations_ibfk_1` FOREIGN KEY (`rep_id`) REFERENCES `rep` (`id`),
CONSTRAINT `openInvitations_ibfk_2` FOREIGN KEY (`customer_macAddr`) REFERENCES `customer` (`macAddr`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1
id select_type Tabellentyp möglichen_Tasten key key_len ref Zeilen Extra 1 EINFACH oi ref PRIMARY, customer_macAddr customer_macAddr 16 const 1 Using where; Index verwenden 1 SIMPLE r eq_ref PRIMARY, FK_rep_1 PRIMARY 66 xxx.oi.rep_id 1 Verwenden von where 1 SIMPLE s eq_ref PRIMARY, FK_subscriber_1 PRIMARY 27 xxx.r.subscriber_id 1 Verwenden von where 1 SIMPLE c eq_ref PRIMARY PRIMARY 4 xxx.s.charge_id 1 Verwenden von where
id select_type Tabellentyp möglichen_Tasten key key_len ref Zeilen Extra 1 EINFACH oi ref PRIMARY, customer_macAddr customer_macAddr 16 const 1 Using where 1 SIMPLE r eq_ref PRIMARY, FK_rep_1 PRIMARY 66 xxx.oi.rep_id 1 Verwenden von where 1 SIMPLE s eq_ref PRIMARY, FK_subscriber_1 PRIMARY 27 xxx.r.subscriber_id 1 Verwenden von where 1 SIMPLE c eq_ref PRIMARY PRIMARY 4 xxx.s.charge_id 1 Verwenden von where
id select_type Tabellentyp möglichen_Tasten key key_len ref Zeilen Extra 1 EINFACH openInvitations ALL customer_macAddr NULL NULL NULL 5258 Verwenden von where
Nach dem Beheben der Abfrage:
id select_type Tabellentyp möglichen_Tasten key key_len ref Zeilen Extra 1 SIMPLE openInvitations ref customer_macAddr customer_macAddr 16 const 1 Using where
EXPLAIN
Ausgabe Ihrer ausgewählten Abfragen bereitstellen undSHOW CREATE TABLE updateTable
uns dabei helfen. Es ist wahrscheinlich ein Indexierungsproblem.Antworten:
Geben Sie, wie DTest hervorhob, weitere Informationen zu Ihrem Problem an.
In Bezug auf das Caching können Sie möglicherweise die Größe Ihres Innodb-Pufferpools erhöhen, damit mehr Daten und Indizes im Speicher zwischengespeichert werden können. Wenn Sie häufig aktualisiert werden, profitieren Sie möglicherweise nicht vom Abfrage-Cache und verwenden diesen RAM möglicherweise besser für den Innodb-Pufferpool.
Wenn Sie alle Ihre Daten und Indizes im RAM ablegen möchten, ist MySQL Cluster möglicherweise Ihre Antwort.
BEARBEITEN
Es sieht so aus, als würden Ihre SELECT-Anweisungen die richtigen Indizes verwenden. Könnten Sie einen Erklärungsplan für Ihre Update-Anweisung bereitstellen? Sie müssen es als SELECT-Anweisung umschreiben, um dies zu tun. Führen Sie
SELECT * FROM
dieselbe Tabelle und dieselbe where-Klausel wie Ihre UPDATE-Anweisung aus.quelle
Das Problem war darauf zurückzuführen, dass in einer meiner OR-Anweisungen im UPDATE kein Schlüssel enthalten war.
Hutspitze zu "dabest1", um mir zu helfen, die Antwort zu finden.
quelle