Eine bestimmte UPDATE Abfrage auf unserer Website läuft manchmal sehr langsam und untersucht viel mehr Zeilen als nötig. Es wird nach dem Primärschlüssel gefiltert, daher würde ich erwarten, dass MySQL immer nur eine Zeile untersuchen müsste.MySQL UPDATE Abfrage nach Primärschlüssel ist manchmal extrem langsam
Hier einige Beispiele aus dem MySQL-Slow-Query-Log:
# Time: 090702 12:59:06
# [email protected]: XXX[XXX] @ XXX [XXX]
# Query_time: 21 Lock_time: 0 Rows_sent: 0 Rows_examined: 500500
SET timestamp=1246532346;
UPDATE `folders` SET `folder_id` = '1705641', `updated_at` = now() WHERE `folders`.`id` = '1682995';
# Time: 090702 14:13:44
# [email protected]: XXX[XXX] @ XXX [XXX]
# Query_time: 17 Lock_time: 0 Rows_sent: 0 Rows_examined: 16816745
SET timestamp=1246536824;
UPDATE `folders` SET `folder_id` = '417997', `updated_at` = now() WHERE `folders`.`id` = '1705956';
# Time: 090702 14:15:42
# [email protected]: XXX[XXX] @ XXX [XXX]
# Query_time: 13 Lock_time: 0 Rows_sent: 0 Rows_examined: 16816719
SET timestamp=1246536942;
UPDATE `folders` SET `folder_id` = '1706267', `updated_at` = now() WHERE `folders`.`id` = '1705956';
# Time: 090702 16:07:43
# [email protected]: XXX[XXX] @ XXX [XXX]
# Query_time: 499 Lock_time: 0 Rows_sent: 0 Rows_examined: 88668449
SET timestamp=1246543663;
UPDATE `folders` SET `folder_id` = '1707407', `updated_at` = now() WHERE `folders`.`id` = '1706992';
Die Abfrage als die häufigen ausgeführt wird, aber so ist es nicht immer dieses Verhalten aussetzen. Auch wenn ich die gleichen Abfragen manuell ausführen, laufen sie gut und kehren sofort zurück.
Ich überprüfte auch die Tabelle und soweit ich es sollte in Ordnung sein sehen:
mysql> describe folders;
+------------------+-----------------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+-----------------------+------+-----+---------------------+----------------+
| id | mediumint(8) unsigned | NO | PRI | NULL | auto_increment |
| user_id | mediumint(8) unsigned | NO | MUL | NULL | |
| folder_id | mediumint(8) unsigned | YES | MUL | NULL | |
| created_at | timestamp | NO | | CURRENT_TIMESTAMP | |
| updated_at | timestamp | NO | | 0000-00-00 00:00:00 | |
| modified_at | timestamp | NO | | 0000-00-00 00:00:00 | |
| name | varchar(255) | NO | | NULL | |
| guest_permission | tinyint(3) unsigned | NO | | 1 | |
+------------------+-----------------------+------+-----+---------------------+----------------+
8 rows in set (0.00 sec)
mysql> show index from folders;
+---------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+---------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| folders | 0 | PRIMARY | 1 | id | A | 760318 | NULL | NULL | | BTREE | |
| folders | 1 | user_id | 1 | user_id | A | 69119 | NULL | NULL | | BTREE | |
| folders | 1 | folder_id | 1 | folder_id | A | 380159 | NULL | NULL | YES | BTREE | |
+---------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
3 rows in set (0.00 sec)
Eine andere Sache ist, dass der MySQL-Server manchmal sperrt und stoppt die Annahme von Verbindungen, und jedesmal, wenn dies geschieht, ich in der Regel finden Sie eine dieser langsamen Abfragen in der Protokolldatei unmittelbar vor dem Fehler. Ich kann keine relevanten Fehlermeldungen in anderen Logfiles sehen, aber ein MySQL-Neustart macht es wieder ansprechbar.
Hat jemand eine Idee, was ist los, oder welche Dinge könnte ich überprüfen, um das Problem einzugrenzen?
EDIT: Wir verwenden MySQL 5.0.51a auf einem dedizierten Server, und derzeit 6 Webserver mit PHP 5.2.6 und Verbindung über PDO mit dem MySQL-Server. Auf allen Servern läuft Debian Lenny. Die langsame Abfrage erfolgt auf allen Webservern.
EDIT: Hier ist ein für ein verwandtes Abfrage ERKLÄREN, mit und ohne Anführungszeichen:
mysql> explain SELECT * FROM `folders` WHERE `folders`.`id` = '1682995';
+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------+
| 1 | SIMPLE | folders | const | PRIMARY | PRIMARY | 3 | const | 1 | |
+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------+
1 row in set (0.00 sec)
mysql> explain SELECT * FROM `folders` WHERE `folders`.`id` = 1682995;
+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------+
| 1 | SIMPLE | folders | const | PRIMARY | PRIMARY | 3 | const | 1 | |
+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------+
1 row in set (0.00 sec)
Das ist wirklich interessant, ich würde gerne wissen, warum es das auch tut. Haben Sie EXPLAIN SELECT * FROM 'Ordner' versucht? WHERE' id' = etwas? –