2 Stimmen

Warum ist diese Abfrage langsam? Sollte ich hier MyISAM statt InnoDB verwenden?

Ich erhalte diese Meldungen etwa 5 Mal pro Stunde in meinen langsamen Abfrageprotokollen:

# Query_time: 11.420629  Lock_time: 0.000033 Rows_sent: 0  Rows_examined: 0
SET timestamp=1267487708;
INSERT INTO record_lock (record_lock.module_id, record_lock.module_record_id, record_lock.site_id, record_lock.user_id, record_lock.expiration_date_time, record_lock.date_time_created) VALUES ('40', '12581', '940', '155254', '2010-03-02 00:24:57', '2010-03-01 23:54:57');

# Query_time: 2.095374  Lock_time: 0.000031 Rows_sent: 0  Rows_examined: 0
SET timestamp=1267488361;
DELETE
FROM record_lock
WHERE record_lock.user_id = 221659 AND record_lock.expiration_date_time IS NOT NULL;

Die Tabelle record_lock verwendet derzeit InnoDB und hat im Moment weniger als ein Dutzend Datensätze in ihr.

Wir haben mehrere tausend aktive Benutzer in unserem System. Jedes Mal, wenn sie einen Datensatz bearbeiten, fügen wir etwas in diese Tabelle ein. Und bei jedem Laden einer beliebigen Seite im System führen wir 1) SELECT aus der Tabelle durch, um zu sehen, ob es Sperren für den aktuellen Benutzer gibt, und 2) eine DELETE-Abfrage für diese Tabelle aus, wenn es Datensätze für den Benutzer gibt, wobei die Primärschlüssel der Tabelle in der WHERE-Klausel referenziert werden.

Hier ist das Schema der Tabelle:

CREATE TABLE IF NOT EXISTS `record_lock` (
  `module_id` int(10) unsigned NOT NULL,
  `module_record_id` int(10) unsigned NOT NULL,
  `site_id` int(10) unsigned NOT NULL,
  `user_id` int(10) unsigned NOT NULL,
  `expiration_date_time` datetime NOT NULL,
  `date_time_created` datetime DEFAULT NULL,
  PRIMARY KEY (`module_id`,`module_record_id`),
  KEY `record_lock_site_id` (`site_id`),
  KEY `index_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

2voto

Jackson Miller Punkte 1432

Wie viele Abfragen führen Sie pro Sekunde durch?

Könnten Sie nicht einfach ein gesperrtes Feld in den Datensatz selbst einfügen? Ich gehe davon aus, dass Sie den Datensatz ohnehin erhalten. Sie könnten auch etwas wie Memcached für die Speicherung der Sperren verwenden.

Ich weiß nicht, die Besonderheiten aus dem Kopf, aber mein Verständnis ist, dass InnoDB ist großartig für gleichzeitige liest, aber saugt für gleichzeitige schreibt. MyISAM könnte besser sein, aber mein Gefühl sagt mir, dass das aktuelle Design fehlerhaft ist.

1voto

Toby Hede Punkte 36095

Haben Sie versucht, ein EXPLAIN auf die Abfragen anzuwenden?

1voto

Jeff Beck Punkte 3939

Liegt es möglicherweise daran, dass zu viele Verbindungen versuchen, auf denselben Tisch zuzugreifen? Sie könnten versuchen, die Tabelle nach user_id zu segmentieren, um das zu vermeiden.

0voto

Martin Punkte 9164

Das Einschalten der Innodb-Monitore kann helfen, die Ursachen für eine schlechte Leistung einzugrenzen:

SHOW ENGINE INNODB STATUS und die InnoDB-Monitore

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X