Orientation syntaxique pour requete restrictive !

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 : Orientation syntaxique pour requete restrictive !

par Atome » 14 nov. 2006, 10:41

Salut,

Voilà j'ai encore appris pas mal de choses, encore merci du gros coup de pouce et vive la doc :-) !

J'ai "réécris" ma requête avec UNION et j'en ai profité pour mieux optimiser mon travail grâce à EXPLAIN ! Les temps de réponses sont ... 100 fois plus rapide ^_^

++

par Atome » 13 nov. 2006, 19:19

Merci de vos réponses rapide !

Il est clair que je m'obstine peut être un peu trop à vouloir faire une requête all in one.

Vu la taille de ma bdd je ne pensais pas devoir faire de l'optimisation ou indexation.

Union et Explain : je crois que je vais potaser demain matin car j'ai visiblement accumulé de grosses lacunes ^_^

A savoir que les deux requêtes séparées s'éxécutent rapidement (~0,01sec)

Merci de m'avoir mis sur la piste !

par Hubert Roksor » 13 nov. 2006, 19:06

Avant toute chose il faut savoir que 1 requête n'est pas forcément plus rapide que 2 requêtes. (1 compliquée versus 2 simples)

Si les deux clauses WHERE sont différentes, alors fusionner 2 requêtes en 1 n'apportera aucun gain de performance et pourra même être beaucoup plus lent. Si tu tiens absolument à unir deux requêtes alors autant utiliser l'opérateur qui est fait pour, UNION

À part ça, comme le dit Cyrano il est difficile de dire comme ça ce qui ne va pas. Commence par te familiariser avec la syntaxe d'EXPLAIN pour te permettre d'optimiser les requêtes SELECT. N'oublie pas de faire un OPTIMIZE TABLE de toutes tes tables de temps à autres et s'il n'y a pas de mieux alors poste le résultat du EXPLAIN des deux requêtes (oublie la mono-requête avec OR pour l'instant).

par Cyrano » 13 nov. 2006, 18:57

On pourrait déjà simplifier un peu comme ceci par exemple :

Code : Tout sélectionner

SELECT DISTINCT (D.id), D.num_aff, D.libelle, T.societe, D.prix FROM devis D, factures_ech E, lignes_fac L, factures F, tiers T WHERE T.id = D.id_tie AND ( ( L.id_dev = D.id AND F.id = L.id_fac AND F.date BETWEEN '2006-10-00' AND '2006-13-00' ) OR ( D.id = E.id_dev AND E.date BETWEEN '2006-10-00' AND '2006-13-00' ) ) GROUP BY D.id ORDER BY D.num_aff;
Mais sans un jeu d'essai, impossible de te dire si ce sera beaucoup mieux. Un autre problème sur l'optimisation des requêtes, c'est l'indexation des colonnes. AJouter certains index accélère notablement l'exécution. Il faudrait voir le schéma de création des différentes tables utilisées.

Problème d'optimisation !

par Atome » 13 nov. 2006, 18:44

Bonjour,

Je réouvre ce topic car en me basant sur la solution proposée ici même je me retrouve avec un délai de réponse astronomique pour peu de résultats.

(+ de 100 secondes pour 70 résultats :( )

Donc je souheterai savoir s'il y a possibilité d'optimiser cette requête ou s'il y a une alternative.

Requête actuelle :

Code : Tout sélectionner

SELECT DISTINCT (D.id), D.num_aff, D.libelle, T.societe, D.prix FROM devis D, factures_ech E, lignes_fac L, factures F, tiers T WHERE ( T.id = D.id_tie AND L.id_dev = D.id AND F.id = L.id_fac AND F.date > '2006-10-00' AND F.date < '2006-13-00' ) OR ( T.id = D.id_tie AND D.id = E.id_dev AND E.date > '2006-10-00' AND E.date < '2006-13-00' ) GROUP BY D.id ORDER BY D.num_aff
Rappel problématique :
Afficher la liste des devis dont au moins une facture ou au moins une échéance existe sur la période donnée.

Infos complémentaires :
La base contient actuellement environ 300 Devis, 300 factures (350 lignes de factures) et à peine une 20ène de factures échelonnées.

Qu'est ce qui ralenti tant l'exécution ?

Merci

par mcorgnet » 30 oct. 2006, 17:03

un ptit clic sur résolu ?

[ Résolu ]

par Atome » 30 oct. 2006, 17:01

Merci Mcorgnet pour ta solution et désolé Cyrano pour l'affichage des requêtes sur une ligne.

Mon premier essai semble me retourner des résultats corrects avec cette façon de procéder.

Maintenant que j'ai la syntaxe je peux progresser et adapter mes besoins finaux.

Merci encore !

par mcorgnet » 30 oct. 2006, 16:42

sourire ...

voui, mais comme atome n'avait pas fait l'effort de nous produire quelque chose de lisible, je ne me sentais pas l'envie d'en faire plus.

m'enfin j'dis ça ...

par Cyrano » 30 oct. 2006, 16:39

Si je peux me permettre : une mise en forme pour rendre une requête lisible couplé à l'utilisation du bouton [code], ça a tout de suite une autre alure :

Code : Tout sélectionner

SELECT * FROM devis D, factures_ech E WHERE (L.id_dev=D.id AND F.id=L.id_fac AND F.date>'2006-10-00' AND F.date<'2006-13-00' ) OR (D.id=E.id_dev AND E.date>'2006-10-00' AND E.date<'2006-13-00' );
Non ?

par mcorgnet » 30 oct. 2006, 16:33

SELECT * FROM devis D, factures_ech E
WHERE (L.id_dev=D.id and F.id=L.id_fac and F.date>'2006-10-00' and F.date<'2006-13-00') OR (D.id=E.id_dev and E.date>'2006-10-00' and E.date<'2006-13-00')

un truc de ce genre ?

attention aux espaces, ça peut foutre la grouille.

Orientation syntaxique pour requete restrictive !

par Atome » 30 oct. 2006, 16:30

Bonjour,

Voilà j'aurai besoin d'un petit coup de pouce car je n'arrive pas à réaliser la requête suivante :

- Afficher la liste des devis dont au moins une facture ou au moins une échéance existe sur la période donnée.

Pour le moment j'ai découpé ma requete en deux (mais pour une question de ressource je souheterai la faire en une fois avec MySQL) :

A - Récupération des devis dont au moins une facture existe
B - Récupération des devis dont au moins une échéance existe

SQL A - select distinct(D.num_aff) from devis D, factures_ech E where D.id=E.id_dev and E.date>'2006-10-00' and E.date<'2006-13-00'

SQL B - select distinct(D.num_aff) from devis D, factures F, lignes_fac L where L.id_dev=D.id and F.id=L.id_fac and F.date>'2006-10-00' and F.date<'2006-13-00'

Les requetes A et B retournent toutes deux des résultats mais si je les combine alors mes résultats ne sont plus du tout correct (tester de différentes manières).

Je pensais que le problème venait de ma vieille syntaxique mais je suis pas sure de bien exploiter les INNER JOIN, LEFT OUTER JOIN etc..

J'ai tenté d'effectuer des count sur les tables "lignes_fac" et "factures_ech" avec des having en fin de requete mais pareil je suis pas certains de correctement l'utiliser (double condition dans le having)

Je vous exposerai bien toutes les formes de requetes que j'ai essayé mais j'ai peur de rendre ce post illisible :)

Voilà j'espère avoir pu être assez clair pour qu'une âme charitable me sorte de cette difficulté.