IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Requêtes MySQL Discussion :

MYSQL : Premier SELECT très long


Sujet :

Requêtes MySQL

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2005
    Messages : 35
    Points : 5
    Points
    5
    Par défaut MYSQL : Premier SELECT très long
    Bonjour

    J'ai une table avec 400 000 enregistrements.
    Elle est en INNODB.

    Le première requête executé et correspondant à l'index est très long.
    Une fois exécuté il est plus rapide, sauf si je ne l'exécute pas de quelque temps.

    Comment remedier à cela ?

    Voici la structure de la table


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    CREATE TABLE IF NOT EXISTS `product` (
      `ID` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
      `description` text COLLATE utf8_unicode_ci NOT NULL,
      `price` decimal(7,2) NOT NULL DEFAULT '0.00',
      `tva` decimal(4,2) NOT NULL DEFAULT '0.00',
      PRIMARY KEY (`ID`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=473580 ;
    Le SELECT :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT `name` FROM `product` WHERE `ID` = 80
    Merci

  2. #2
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Bonjour,

    - que veut dire très long ?
    - par 1er qu'entendez-vous ? après un arrêt / relance du serveur ?
    - combien de Go/Mo fait votre bdd ? vos indexes ?
    - qu'avez-vous comme valeur pour le paramètre : innodb_buffer_pool_size ?

  3. #3
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Normalement, et vu la structure de la table, la réponse devrait être immédiate.
    Ce temps très long est-il constaté directement sur le serveur MySQL ou via une application ?
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2005
    Messages : 35
    Points : 5
    Points
    5
    Par défaut
    Il faut bien compter 70 secondes.

    Cela correspond a un arrêt relance effectivement.

    La base fait 21 Mo.

    innodb_buffer_pool_size fait 8 Mio

    La requête est exécutée via PHPMyAdmin

  5. #5
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Citation Envoyé par re12 Voir le message
    Il faut bien compter 70 secondes.

    Il y a quelque chose qui ne va pas quelque part !

    Un détail que je viens de constater :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CREATE TABLE IF NOT EXISTS `product`
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT `name` FROM `bo_product`
    tu n'interroges pas la table dont tu nous as donné la structure !
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2005
    Messages : 35
    Points : 5
    Points
    5
    Par défaut
    Effectivement j'ai corrigé cette partie dans le premier post.

    Pensez vous qu'il y a une mise en cache qui est faite la première fois? étonnant qu'elle soit si longue?

  7. #7
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    La piste que j'aurai par rapport à ca c'est que MYSql met 70 sec pour soit (ou un mix des deux) :
    - charger en mémoire votre index.
    - retrouver sur disque les informations liées à votre ligne (et les mettre en mémoire).

    Donc ...
    - est-ce un serveur dédié
    - y a-t-il d'autre database MySql qui tourne sur la même instance qui pourrai utiliser ces 8mo de innodb_buffer_pool_size
    - vos disques sont-ils ok
    - y aurai-t-il un lock par une appli de votre table production lors du lancement du serveur ?
    - etc ...

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2005
    Messages : 35
    Points : 5
    Points
    5
    Par défaut
    Alors c'est une machine virtuelle pour le moment (l'application est en cours de développement)

    Il n'y a pas de soucis de perf sur cette machine elle fonctionne plutôt bien.

    C'est la seule application sur la machine.

  9. #9
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    L'index étant une clé primaire entière, Même avec plus de 400 000 lignes, il doit être petit.
    Même sur un simple PC de base, une telle requête devrait s'exécuter en moins de temps qu'il faut pour lever le nez du clavier vers l'écran après avoir tapé la touche Entrée !

    J'ai fait des requêtes autrement plus complexes sur un simple portable d'il y a 4 ans et sur plusieurs tables jointes contenant des millions et dizaines de millions de lignes avec une réponse inférieure à 5 secondes.

    Il y a soit un problème de config, soit un problème matériel. 70 secondes, c'est une éternité pour un SGBD !
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  10. #10
    Futur Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2005
    Messages : 35
    Points : 5
    Points
    5
    Par défaut
    Bonsoir,

    Effectivement après recherche ce n'est pas cette requête qui posait problème...

    Voici la fautive :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT COUNT(1) as "total" FROM 
    (
    	SELECT `ID` as "ID",`name` as "name",`price` as "price",`tva` as "tva"
    	FROM `product` 
    	WHERE 1 = 1 
    ) deriv;
    Le but de cette requête est de compter le nombre total de ligne qu'aurai pu retourner la sous requête si il n'y avais pas eu de LIMIT.

    J'ai vu qu'il était possible d'utiliser SQL_CALC_FOUND_ROWS pour récupérer cette valeur, seulement elle retourne la valeur pour la dernière requête exécutée, et cela est risquée pour mon application qui as plusieurs utilisateurs connectés en même temps.


    Une idée?

    Bonne soirée à vous

  11. #11
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Euh... on n'est plus du tout avec la même requête qu'au début là !

    Ta sous requête ne fait rien d'autre que ramener toutes les lignes de la table puis que WHERE 1 = 1 est toujours vrai.

    Du coup le COUNT de la requête principale ne fait que compter les lignes de la table, ce qui est équivalent à cette requête beaucoup plus simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT COUNT(*) AS nb_lignes
    FROM product
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  12. #12
    Membre expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Points : 3 295
    Points
    3 295
    Billets dans le blog
    1
    Par défaut
    salut,

    faut pas passer par ça pour savoir le nombre total de ligne sans limit, y a une syntaxe spéciale pour ça...found_rows()

    en plus, comme le dit cinephil autan faire un count direct sur l'id de ta table vu ce que tu fais comme requête...
    soyons pensez à mettre quand votre problème est résolu ou à utiliser pour les réponses pertinentes...
    ne posez pas de problématique soi-disant simplifiée sur des problèmes que vous n'êtes pas capable de résoudre par respect pour ceux qui planchent dessus... sinon: et à utiliser pour insérer votre code...

  13. #13
    Futur Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2005
    Messages : 35
    Points : 5
    Points
    5
    Par défaut
    Alors effectivement je n'ai pas expliqué la raison d'être de cette requête.

    Mais en reprenant ça je pense pouvoir faire autrement effectivement.

    Je reviens vers vous des que j'ai trouvé la solution.
    Merci pour vos réponses.

  14. #14
    Futur Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2005
    Messages : 35
    Points : 5
    Points
    5
    Par défaut
    Bonjour,

    En faisant un

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT COUNT(*) AS nb_lignes
    FROM product
    sur une base en INNODB avec 20 millions de ligne la requête met 20 secondes à s'exécuter.

    Pensez vous qu'il y a moyen d'optimiser cela?
    J'ai vu qu'en INNODB cette requête allait lire tout les enregistrements comparé à MyISAM qui va chercher les stats de la table

  15. #15
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    J'ai vu qu'en INNODB cette requête allait lire tout les enregistrements comparé à MyISAM qui va chercher les stats de la table
    Tu as vu ça où ?

    Si ta table est normalement constituée, elle possède une clé primaire qui, par définition, est indexée. En faisant un COUNT(*) sur une table, sans autre condition, le SGBD doit, normalement, se contenter de calculer la profondeur de l'index de clé primaire. Il ne va pas parcourir toute la table pour en compter une à une les lignes.

    Avec cette méthode, compter même 20 millions de lignes doit se faire en une fraction de seconde.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  16. #16
    Futur Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2005
    Messages : 35
    Points : 5
    Points
    5

  17. #17
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    J'penses que MySql a le même problème que postGresql a ce stade là.

    http://dev.mysql.com/doc/refman/5.5/...trictions.html

    •InnoDB does not keep an internal count of rows in a table because concurrent transactions might “see” different numbers of rows at the same time. To process a SELECT COUNT(*) FROM t statement, InnoDB scans an index of the table, which takes some time if the index is not entirely in the buffer pool. If your table does not change often, using the MySQL query cache is a good solution. To get a fast count, you have to use a counter table you create yourself and let your application update it according to the inserts and deletes it does. If an approximate row count is sufficient, SHOW TABLE STATUS can be used. See Section 14.3.14.1, “InnoDB Performance Tuning Tips”.

  18. #18
    Futur Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2005
    Messages : 35
    Points : 5
    Points
    5
    Par défaut
    pensez vous que je puisse utiliser un autre moteur de stockage ?

    Sachant que j'utilise INNODB pour les transactions.

    Merci

  19. #19
    Membre expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Points : 3 295
    Points
    3 295
    Billets dans le blog
    1
    Par défaut
    c'est bizarre en effet... tu as accès à la configuration de mysql?

    regarde la taille du buffer pour les index de base c'est: key_buffer_size = 16M

    fait un:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    show table status from ta_bd
    et regarde "index length" dans la ligne correspondant au nom de ta table

    si tu as beaucoup d'insertion/suppression, il faut faire plus ou moins fréquemment un:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    optimize table ta_table;
    pour compacter la table et l'index et éviter leur fragmentation
    soyons pensez à mettre quand votre problème est résolu ou à utiliser pour les réponses pertinentes...
    ne posez pas de problématique soi-disant simplifiée sur des problèmes que vous n'êtes pas capable de résoudre par respect pour ceux qui planchent dessus... sinon: et à utiliser pour insérer votre code...

  20. #20
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Citation Envoyé par re12 Voir le message
    J'en pense que ce billet date de 2006 et j'espérais que le problème fut corrigé depuis.

    Avec le lien et la citation donnés par Punkoff, il semble que ce ne soit pas le cas.
    Cependant, la citation confirme ma supposition :
    To process a SELECT COUNT(*) FROM t statement, InnoDB scans an index of the table
    Donc je persiste à dire que même avec 20 millions de lignes, ça devrait être très rapide.

    Applique la procédure de ericd69 et réessaie le comptage.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

Discussions similaires

  1. Driver JDBC et Oracle - select très long
    Par mgax07 dans le forum JDBC
    Réponses: 5
    Dernier message: 20/02/2014, 10h03
  2. [Perfs] Insert+select très long
    Par farenheiit dans le forum Administration
    Réponses: 39
    Dernier message: 07/08/2009, 14h36
  3. Démarrage de windows vraiment très long
    Par krfa1 dans le forum Windows XP
    Réponses: 16
    Dernier message: 23/10/2005, 12h37
  4. delete très long
    Par slefevre01 dans le forum Oracle
    Réponses: 7
    Dernier message: 06/10/2005, 13h16
  5. Très long texte dans Quick Report - Comment faire ?
    Par delphi+ dans le forum Composants VCL
    Réponses: 2
    Dernier message: 21/08/2005, 22h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo