J'ai un simple tableau avec des millions d'enregistrements (14 000 000) et pour une simple requête, il passe trop de temps à "envoyer des données".
La table
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;
La simple requête
mysql> SELECT * FROM details WHERE id = 3014595;
Explique
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 pour la requête
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 |
+--------------------------------+----------+
Comme vous pouvez le voir, l' SELECT
instruction a utilisé l'index et n'a lu que 1482 lignes. Pourtant, la requête a mis 7,536960 secondes pour envoyer les données. C'est comme si la requête lisait beaucoup plus de lignes dont elle avait besoin.
Il s'agit d'une requête simple, avec seulement 7 champs (ligne moyenne 59 octets) et aucune fonction fantaisie. Une idée de ce qui peut en être la cause?
Remarque: id est l'ID utilisateur. Chaque utilisateur peut avoir au moins une entrée pour chaque heure de chaque jour. Par conséquent, id n'est pas unique.
Edit: J'ai un autre tableau avec la même structure et beaucoup plus de lignes (34 millions). Si j'exécute la même requête sur cette table plus grande, elle renvoie les résultats en moins d'une seconde.
La seule différence est que la plus grande table n'obtient pas autant de requêtes que la petite table.
- Est-il possible que le nombre de requêtes ralentisse le processus? Le cache MySQL est activé. J'ai également mis en cache CakePHP les requêtes pour réduire le nombre de requêtes.
- Est-il possible que le fichier où la table est enregistrée est corrompu ou quelque chose?
Mise à jour Le problème a été résolu en séparant le niveau de données du niveau Web. Le niveau de données a également obtenu une mise à niveau sur la RAM et fonctionne sur raid10.
la source
SELECT
retour?1591 rows in set (16.48 sec)
J'ai relancé la requête, c'est pourquoi la durée est différente. Cela a pris maintenant 16 secondes (!!)Réponses:
Pour tous ceux qui trébuchent sur cette question et se demandent, même sans mise à niveau de la RAM, pourquoi l'envoi de données prenait beaucoup plus de temps. C'est parce que l'envoi de données inclut en fait le temps de recherche des données qui doivent être envoyées.
https://dev.mysql.com/doc/refman/5.7/en/general-thread-states.html
la source
Essayez d'optimiser la table à l'aide du nom de table Optimiser la table et vérifiez l'état.
De grands changements doivent être effectués:
Cela vous aidera beaucoup et peut-être qu'il devrait y avoir une clé primaire dans le tableau, mais vous avez ajouté trois colonnes comme clé primaire.
la source
Créez un index distinct pour l'id:
Pour appliquer cet index, redémarrez MySQL ou
Si possible, vous pouvez également modifier la base de données en InnoDB pour la prise en charge des transactions et d'autres avantages.
la source