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

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : optimisation de grande table (requete lente),requete croisée

par Hubert Roksor » 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.

par Ajoloca » 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.

par zeus » 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.

par Ajoloca » 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.

par zeus » 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

par pifou » 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... )

par Invité » 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

par Hubert Roksor » 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

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

par Invité » 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