mysql prend trop de temps pour envoyer des données


9

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' SELECTinstruction 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.


Combien de lignes le SELECTretour?
hjpotter92

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 (!!)
rlcabral

au lieu d'utiliser * essayez d'utiliser des colonnes et voyez quelle différence cela fait
Muhammad Raheel

Nan. Même résultat.
rlcabral

Essayez de faire de la colonne ID un simple index primaire. Comme l'ID doit être un champ unique, vous n'avez pas besoin de faire des index complexes avec lui. Cela devrait rendre votre recherche par clé primaire rapide comme une vitesse lumineuse.
Alexander Pravdin

Réponses:


1

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

Le thread lit et traite les lignes d'une instruction SELECT et envoie des données au client. Étant donné que les opérations qui se produisent pendant cet état ont tendance à effectuer de grandes quantités d'accès au disque (lectures), il s'agit souvent de l'état le plus long sur la durée de vie d'une requête donnée.


-2

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:

Alter table tablename engine = 'INNODB'

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.


-3

Créez un index distinct pour l'id:

modifier les détails de la table ajouter la clé d1 (id);

Pour appliquer cet index, redémarrez MySQL ou

analyser les détails du tableau;

Si possible, vous pouvez également modifier la base de données en InnoDB pour la prise en charge des transactions et d'autres avantages.


Comment cela va-t-il aider?
Colin 't Hart
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.