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

SQL Oracle Discussion :

Demande d'aide pour une requête SQL trop coûteuse [11g]


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Juillet 2005
    Messages
    41
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 41
    Par défaut Demande d'aide pour une requête SQL trop coûteuse
    Bonjour à tous,


    Je sollicite votre aide car je suis coincé sur une requête SQL.

    Pour simplifier le problème, imaginons que j'ai une table qui contient les champs suivants :
    type, sous_type, nature, date, statut

    Le besoin est de connaître pour chaque triplet (type, sous_type, nature,) le nombre d'enregistrements dont la date est supérieure au 1er janvier 2019 et dont le statut est égal à 1.

    Jusqu'ici c'est très simple, mais la requête doit aussi retourner les triplets qui ne répondent pas à ces deux critères.

    Un petit exemple :
    Si ma table contient les enregistrements suivants :
    type1, sous_type1, nature1, '01/01/2019', 1
    type1, sous_type1, nature1, '01/02/2020', 1
    type1, sous_type1, nature1, '01/01/2019', 2
    type1, sous_type1, nature1, '31/12/2018', 1
    type2, sous_type1, nature1, '01/01/2019', 1
    type3, sous_type1, nature1, '31/12/2018', 1

    alors la requête doit retourner les enregistrements suivants :
    type1, sous_type1, nature1, 2
    type2, sous_type1, nature1, 1
    type3, sous_type1, nature1, 0

    J'ai donc construit la requête suivante, sans trop me soucier au départ des performances d'exécution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    select distinct
    	t1.type,
    	t1.sous_type,
    	t1.nature
    	(select count(*) from table t2
    	 where t2.type = t1.type
    	 and t2.sous_type = t1.sous_type
    	 and t2.nature = t1.nature
    	 and t2.statut = 1
    	 and to_char(t2.date,'DD/MM/YYYY') >= '01/01/2019'
    	) total
    from table t1;
    J'ai testé en filtrant sur un seul triplet, ça fonctionne.
    Le problème en revanche c'est que ma table contient un très grand nombre d'enregistrements et en conséquence, la requête est beaucoup trop coûteuse en terme de performances (le plan d'exécution indique que la requête est 100.000 fois plus coûteuse !).

    J'ai le sentiment que la requête n'est pas optimisée et/ou mal construite, j'ai tenté de passer par une auto-jointure externe mais je n'ai pas réussi à retrouver les mêmes résultats.

    Pourriez-vous me dire comment construire ma requête pour qu'elle soit le plus efficace possible ?

    Ce qui est assez frustrant c'est que je peux exécuter deux requêtes qui s'exécutent très rapidement, la première liste tous les triplets et la seconde uniquement ceux qui répondent aux critères, et après je peux faire la fusion dans Excel mais je pense qu'une requête SQL bien construite pourrait faire ce travail directement

    Merci d'avance pour votre aide, j'ai passé la journée dessus et vous êtes mon dernier espoir


    Cordialement,
    Sylvain

  2. #2
    Membre Expert
    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Décembre 2019
    Messages
    1 175
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Décembre 2019
    Messages : 1 175
    Par défaut
    Bonjour,

    C'est un cas d'utilisation classique de fonction d'agrégat avec CASE. Tu peux faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    select t1.type,
    	 t1.sous_type,
    	 t1.nature,
             count(case when t1.date >= to_date('01/01/2019', 'DD/MM/YYYY') then distinct.date end)
    from table t1
    where t1.statut = 1
    group by t1.type,
    	     t1.sous_type,
    	     t1.nature ;
    J'ai utilisé DISTINCT dans le count car j'ai l'impression que c'est ce que tu souhaites. Par contre pourquoi ta sous-requête interroge une table t2, y-a-t-il une 2è table?
    J'ai laissé "date" pour le nom de ta colonne mais ce n'est pas possible c'est un nom réservé.

  3. #3
    Membre averti
    Inscrit en
    Juillet 2005
    Messages
    41
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 41
    Par défaut
    Bonjour,


    Merci beaucoup pour ton aide qui a permis de débloquer la situation

    En effet je ne connaissais pas la possibilité d'utiliser la clause case dans une clause count, c'est très utile !

    J'ai dû modifier légèrement le contenu de la clause case pour que ça fonctionne, et la requête s'exécute très rapidement.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    select t1.type,
    	 t1.sous_type,
    	 t1.nature,
             count(case when t1.date >= to_date('01/01/2019', 'DD/MM/YYYY') then 1 else null end)
    from table t1
    where t1.statut = 1
    group by t1.type,
    	     t1.sous_type,
    	     t1.nature ;
    Pour répondre à ta question j'ai bien une seule table, mais j'étais obligé de passer par deux alias et un distinct avec ma méthode initiale qui est à oublier


    Merci encore.
    Sylvain

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. aide pour une requête sql/plpgsql
    Par viny dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 09/11/2007, 11h32
  2. Réponses: 2
    Dernier message: 02/03/2006, 11h57
  3. Besoin d'aide pour une requête SQL
    Par Borami dans le forum Langage SQL
    Réponses: 1
    Dernier message: 07/11/2005, 10h33
  4. Demande d'aide pour une requête
    Par arkzor dans le forum Requêtes
    Réponses: 3
    Dernier message: 28/12/2004, 02h40
  5. Besoin d'aide pour une Requête SQL ...
    Par Kokito dans le forum Requêtes
    Réponses: 2
    Dernier message: 07/07/2004, 11h56

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