optimisation de grande table (requete lente),requete croisée

Invité
Invité n'ayant pas de compte PHPfrance

08 janv. 2007, 12:51

Bonjour,

J'ai plusieurs petites questions :

1) Sur mon site j'ai plusieurs tables qui commencent à prendre de l'importance à savoir plus de 100000 enregistrements, cela rend les requete de plus en plus longue..... quelqu'un aurait une solution pour acceler la requete (reorganisation de table.....) ?

2) La deuxième question a pour but (je pense d'acceler le tout) je m'explique : j'ai une table interventions (~100000 enregistrements)qui enregistre toutes les opérations que font les salariés sur une gamme de produits dans une table produits (15000 produits).
Dans la table interventions il y a une colonne date et dans la table produits , les details de chaque produit
Lorsque je veux obtenir les interventions et les details sur un produit (journal par date), cela prend dix plombes pour obtenir le resultat (c'est à dire quand je vais chercher tous les id_produit dans la table interventions) . C'est tout aussi long quand je vais chercher des "vieilles" interventions.

3) comment faire en une requete pour obtenir à la fois des données de la table interventions et les détails du produit correspondant de la table produits

J'espère avoir été clair :?

Merci d'avance

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

08 janv. 2007, 13:05

Il y a tout un chapitre dans la doc MySQL : Optimisation, tout spécialement le chapitre 7.2. Apprends à lire le résultat d'EXPLAIN, vérifie les indices et tout ça. Si tu as toujours besoin d'aide, poste des exemples concrets de requêtes et le résultat d'EXPLAIN. Je te recommande d'utiliser le client MySQL en ligne de commande plutôt que phpMyAdmin car il formatte le résultat de façon directement exploitable dans les balises

Invité
Invité n'ayant pas de compte PHPfrance

08 janv. 2007, 18:13

Cool pour l'explain, merci, grace à ca, j'ai réussi à passer de 3min à moins de 10 sec :D , encore un petit effort pour mieux optimiser :lol:

En utilisant une requte au lieu de deux il doit etre possible d'optimiser le tout ?

Voici les deux requêtes pour obtenir les caracteristiques des produits sur lesquels il y a eu une intervention en septembre 2006 :

Code : Tout sélectionner

select disctinct id_produit from interventions where date_mois='2006.09'
puis

Code : Tout sélectionner

select nom, reference, prix, couleur, poids from produits where id='id_produit' order by reference asc
Est-il possible de transformer ces deux requetes en une seule ?
Si oui, comment ?

Merci d'avance

Petit nouveau ! | 5 Messages

08 janv. 2007, 18:48

tu veux sélectionner tous les produits qui ont eu une intervention en '2006.09'? alors une sous requete me semble adaptée:

Code : Tout sélectionner

select nom, reference, prix, couleur, poids FROM produits WHERE id IN (SELECT id_produit FROM interventions WHERE date_mois='2006.09') ORDER BY reference asc
( en espérant que ta version mysql l'accepte... )

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

08 janv. 2007, 18:54

Tu peut aussi faire une jointure, ce qui devrais être beaucoup plus performant qu'une sous-requete ;)

Code : Tout sélectionner

SELECT nom, reference, prix, couleur, poids FROM produits p JOIN interventions i ON p.id = i.id_produit WHERE i.date_mois = '2006.09' ORDER BY reference ASC
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

ViPHP
ViPHP | 1961 Messages

08 janv. 2007, 19:03

Bonjour,

Je suppose que ce qu'il cherche c'est une description unique du produit, si c'est le cas,
Je pense que vos requêtes de zeus et de pifou ont le même PB.

Si on trouve plusieurs interventions dans la table 'interventions' pour un même produit, on aura autant de fois la description du produit.

Quant aux requêtes imbriquées, je ne suis pas sur que ce soit plus rapide que deux requêtes séparées.
Deux choses sont infinies, l'Univers et la sottise humaine!!
Mais je ne suis pas sur de ce que j'affirme au sujet de l'Univers.

A. Einstein

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

08 janv. 2007, 19:15

Si on trouve plusieurs interventions dans la table 'interventions' pour un même produit, on aura autant de fois la description du produit.
Effectivement.
Quoique la requête de pifou, même s'il retourne plusieurs fois les interventions, ne sélectionnera qu'une seule fois chaque produit. Un DISTINCT pourrais résoudre ce soucis.
Dans ma requête, je suis sûr qu'en farfouillant dans les différents types de JOINTURE, on devrait résoudre ce soucis ;)
Quant aux requêtes imbriquées, je ne suis pas sur que ce soit plus rapide que deux requêtes séparées.
On doit juste gagner le temps de transmission des données.
Par contre, je reste persuadé qu'une jointure est plus rapide que 2 requêtes.
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

ViPHP
ViPHP | 1961 Messages

08 janv. 2007, 19:20

Re,
On doit juste gagner le temps de transmission des données.
Je ne suis pas sur que l'on gagne du temps car MySQL doit créer des tables temporaires supplémentaires.
Par contre, je reste persuadé qu'une jointure est plus rapide que 2 requêtes.
C'est indiscutable.
Deux choses sont infinies, l'Univers et la sottise humaine!!
Mais je ne suis pas sur de ce que j'affirme au sujet de l'Univers.

A. Einstein

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

09 janv. 2007, 03:55

Est-il possible de transformer ces deux requetes en une seule ?
Si oui, comment ?
L'étape numéro 1 est de nous montrer l'EXPLAIN qui va avec chaque requête. Selon le profil de la requête ça peut simplement ne pas en valoir la peine.
Je ne suis pas sur que l'on gagne du temps car MySQL doit créer des tables temporaires supplémentaires.
Le "SELECT DISTINCT" en créera une s'il n'y a pas d'index sur la colonne en question, sinon pas besoin. L'autre requête en a besoin d'une si la colonne utilisée pour le ORDER BY n'est pas indexée, sinon, là encore ça doit se faire sans table temporaire. C'est pour ça que j'insiste sur la présence d'un EXPLAIN parce que beaucoup de paramètres entrent en ligne de compte. Selon les indices, une requête avec une jointure simple pourrait ne pas créer de table temporaire, mais si elle le doit ça vaut peut-être la peine d'utiliser une table dérivée pour recenser les "id_produit" DISTINCTs.