Ich habe eine einfache Tabelle mit Millionen von Datensätzen (14.000.000) und für eine einfache Abfrage verbringt sie zu viel Zeit mit dem "Senden von Daten".
Der Tisch
CREATE TABLE IF NOT EXISTS details (
id int(11) NOT NULL,
date date NOT NULL,
time int(2) NOT NULL,
minutes_online decimal(5,0) NOT NULL,
minutes_playing decimal(5,0) NOT NULL,
minutes_chatting decimal(5,0) NOT NULL,
minutes_away decimal(5,0) NOT NULL
PRIMARY KEY (id,date,time)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
Die einfache Abfrage
mysql> SELECT * FROM details WHERE id = 3014595;
Erklären
mysql> EXPLAIN SELECT * FROM details WHERE id = 3014595;
+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------+
| 1 | SIMPLE | details | ref | PRIMARY | PRIMARY | 4 | const | 1482 | |
+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------+
Profil für die Abfrage
mysql> SHOW PROFILE FOR QUERY 1;
+--------------------------------+----------+
| Status | Duration |
+--------------------------------+----------+
| starting | 0.000024 |
| checking query cache for query | 0.000078 |
| checking permissions | 0.000014 |
| Opening tables | 0.000126 |
| System lock | 0.000011 |
| Table lock | 0.000030 |
| init | 0.000027 |
| optimizing | 0.000117 |
| statistics | 0.040077 |
| preparing | 0.000029 |
| executing | 0.000006 |
| Sending data | 7.536960 |
| end | 0.000013 |
| query end | 0.000004 |
| freeing items | 0.000037 |
| storing result in query cache | 0.000006 |
| logging slow query | 0.000003 |
| cleaning up | 0.000006 |
+--------------------------------+----------+
Wie Sie sehen können, hat die SELECT
Anweisung den Index verwendet und nur 1482 Zeilen gelesen. Die Abfrage dauerte jedoch 7,536960 Sekunden, um die Daten zu senden. Es ist, als würde die Abfrage viel mehr Zeilen lesen, die sie benötigt.
Es ist eine einfache Abfrage mit nur 7 Feldern (Zeile durchschnittlich 59 Bytes) und ohne ausgefallene Funktion. Irgendeine Idee, was dies verursachen kann?
Hinweis: id ist die Benutzer-ID. Jeder Benutzer kann mindestens einen Eintrag für jede Stunde eines jeden Tages haben. Daher ist id nicht eindeutig.
Bearbeiten: Ich habe eine andere Tabelle mit der gleichen Struktur und viel mehr Zeilen (34 Millionen). Wenn ich dieselbe Abfrage für diese größere Tabelle ausführe, werden die Ergebnisse in weniger als 1 Sekunde zurückgegeben.
Der einzige Unterschied besteht darin, dass die größere Tabelle nicht so viele Abfragen erhält wie die kleinere Tabelle.
- Ist es möglich, dass die Anzahl der Abfragen den Prozess verlangsamt? Der MySQL-Cache ist aktiviert. Ich habe auch CakePHP zwischengespeichert, um die Anzahl der Abfragen zu reduzieren.
- Ist es möglich, dass die Datei, in der die Tabelle gespeichert ist, beschädigt ist oder so?
Update Das Problem wurde behoben, indem die Datenschicht von der Webschicht getrennt wurde. Die Datenschicht hat auch ein Upgrade im RAM erhalten und läuft auf raid10.
quelle
SELECT
Rückgabe?1591 rows in set (16.48 sec)
Ich habe die Abfrage erneut ausgeführt. Aus diesem Grund ist die Dauer unterschiedlich. Es dauerte jetzt 16 Sekunden (!!)Antworten:
Für alle, die über diese Frage stolpern und sich auch ohne RAM-Upgrade fragen, warum das Senden von Daten so viel länger dauert. Dies liegt daran, dass das Senden von Daten tatsächlich die Zeit für die Suche nach den zu sendenden Daten umfasst.
https://dev.mysql.com/doc/refman/5.7/en/general-thread-states.html
quelle
Versuchen Sie, die Tabelle mithilfe des Tabellennamens "Tabelle optimieren" zu optimieren, und überprüfen Sie den Status.
Es müssen große Änderungen vorgenommen werden:
Dies wird Ihnen viel helfen und möglicherweise sollte es einen Primärschlüssel in der Tabelle geben, aber Sie haben drei Spalten als Primärschlüssel hinzugefügt.
quelle
Erstellen Sie einen separaten Index für die ID:
Starten Sie MySQL oder neu, um diesen Index in Kraft zu setzen
Wenn möglich, können Sie die Datenbank auch in InnoDB ändern, um Transaktionsunterstützung und andere Vorteile zu erhalten.
quelle