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 :

Optimisation d'une requête


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné
    Profil pro
    Développeur freelance
    Inscrit en
    Août 2006
    Messages
    453
    Détails du profil
    Informations personnelles :
    Localisation : France, Ardèche (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur freelance

    Informations forums :
    Inscription : Août 2006
    Messages : 453
    Par défaut Optimisation d'une requête
    Bonjour,

    j'ai réalisé une requête, je tiens à dire que je suis loin d'être un expert, contenant un UNION ALL.
    Voici ce que m'a requête est censé faire :
    Dans une table je souhaite récupérer les 10 premiers lignes correspondant à un type (valeur d'un champ) ainsi que les 10 premières lignes correspondant à un autre type, voici la requête que j'ai réalisé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    	select *	   
    	from TABLE_A a, TABLE_B b
    	where a.CATEGORY_TYPE = 1
    		and a.TERMINAL IS NOT NULL
    		and a.CATEGORY <> b.VALEUR
    		and ROWNUM <= 10
    	UNION ALL
    	select *
    	from TABLE_A a, TABLE_B b
    	where  a.CATEGORY_TYPE = 2
    		and a.TERMINAL IS NOT NULL
    		and a.CATEGORY <> b.VALEUR
    		and ROWNUM <= 10
    J'ai simplifié ma requête afin de mettre en lumière le UNION ALL qui me pose problème.

    Cependant après analyse je m'en rend compte que cette requête est bien trop coûteuse, et je voudrais savoir s'il y a une manière de réaliser la même chose avec des fonctions oracle. Je voudrais pouvoir me passer de UNION ALL.

    N'hésitez pas à me donner des pistes et/ou à me dire s'il vous faut plus d'informations.

    Mosco

  2. #2
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 953
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 953
    Par défaut
    1/ Quand on parle des 10 premières lignes, ça impliquent un tri, dans l'exemple proposé il n'y a pas de tri donc juste 10 lignes au hazard.
    2/ L'union de 2 ensembles de 10 lignes n'est pas couteux, UNION ALL n'est l'origine du problème
    3/ Le gros problème vient de votre condition de jointure sur un "différent de".

    L'utilisation de NOT EXISTS à la place de la jointure pourraît peut être convenir, ainsi que celle de row_number à la place de rownum pour éviter l'union.
    Quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
      with t as (
    select a.* --pas étoile, mais la liste des colonnes
         , row_number() over (partition by a.CATEGORY_TYPE order by /*le critère de tri*/) as rn
      from TABLE_A a
     where a.CATEGORY_TYPE in (1, 2)
       and a.TERMINAL IS NOT NULL
       and not exists (select 1 
                         from TABLE_B b 
                        where b.VALEUR = a.CATEGORY)
    )
    select *
      from t
     where rn <= 10
    Sinon, précisez votre besoin, et par ailleurs quels sont les index en présence et la volumétrie des 2 tables ?

  3. #3
    Membre chevronné
    Profil pro
    Développeur freelance
    Inscrit en
    Août 2006
    Messages
    453
    Détails du profil
    Informations personnelles :
    Localisation : France, Ardèche (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur freelance

    Informations forums :
    Inscription : Août 2006
    Messages : 453
    Par défaut
    merci pour le retour je vais regarder les différents points.

    Je me rends compte que j'ai un peu trop simplifié ma requête , voici la requête moins simplifiée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    	select *	   
    	from TABLE_A a, TABLE_B b
    	where a.CATEGORY_TYPE = 1
    		and a.TERMINAL IS NOT NULL
    		and a.CATEGORY <> b.VALEUR
    		and ROWNUM <= 100000 -- en fait la vraie valeur est 100000 et non 10
    	UNION ALL
    	select *
    	from TABLE_A a, TABLE_B b
    	where  a.CATEGORY_TYPE = 2
    		and a.TERMINAL IS NOT NULL
    		and a.CATEGORY <> b.VALEUR
    		and ROWNUM <= 100000 -- en fait la vraie valeur est 100000 et non 10
    	order by CATEGORY_REQ_TIME DESC
    Concernant la volumétrie, la table b ne contient que plusieurs dizaines de lignes (table de configuration) alors que la table a peut contenir des centaines de milliers de lignes (ma base de test en contient 90000).
    D'où mon remplacement de 10 par 10000 qui correspond à la vraie valeur dans ma requête (je ne pensais pas que cela avait une importance )

    Promis cette fois j'ai juste changer le nom des tables.

    Concernant les index utilisés par ma requête :
    - pas d'index sur ma table b
    - table a :
    - un index sur CATEGORY
    - un index sur TERMINAL
    - je n'ai pas listé les autres index dont les champs ne sont pas utilisés dans ma requête mais il s'agit peut être d'un tord ?

    Je peux rajouter d'autres index si nécessaire.

    N'hésitez pas si vous pensez qu'il vous faut d'autres informations.

    Mosco

  4. #4
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 953
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 953
    Par défaut
    100000 n'a de sens que si vous êtes en train de générer un fichier, sinon pour un humain sur un écran, 100000 lignes c'est beaucoup trop.

  5. #5
    Membre chevronné
    Profil pro
    Développeur freelance
    Inscrit en
    Août 2006
    Messages
    453
    Détails du profil
    Informations personnelles :
    Localisation : France, Ardèche (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur freelance

    Informations forums :
    Inscription : Août 2006
    Messages : 453
    Par défaut
    Citation Envoyé par skuatamad Voir le message
    100000 n'a de sens que si vous êtes en train de générer un fichier, sinon pour un humain sur un écran, 100000 lignes c'est beaucoup trop.
    C'est pour envoyer à un autre traitement pas pour de l'affichage, j'avais oublié de le préciser.

  6. #6
    Membre Expert
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Avril 2013
    Messages
    2 005
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2013
    Messages : 2 005
    Par défaut
    Mosco, quand tu dis que ta requête est trop coûteuse, ça signifie quoi? En temps je suppose mais elle met combien de seconde à s'exécuter?

    Tu peux nous afficher le plan d'exécution et les stats en faisant un AUTOTRACE? Ca nous aidera à y voir plus clair.
    Au fait, les stats de ton schéma sont à jour?

    Est-ce qu'il y a un index sur a.CATEGORY_TYPE? Si non, pourquoi?

  7. #7
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 953
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 953
    Par défaut
    Citation Envoyé par MoscoBlade Voir le message
    C'est pour envoyer à un autre traitement pas pour de l'affichage, j'avais oublié de le préciser.
    Ok, travaillez en priorité sur la relation avec la table B, voir si NOT EXISTS convient, ou autre, car en l'état la condition de jointure est catastrophique.

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

Discussions similaires

  1. Optimisation d'une requête
    Par Louis-Guillaume Morand dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 20/12/2005, 18h21
  2. Optimisation d'une requête d'insertion
    Par fdraven dans le forum Oracle
    Réponses: 15
    Dernier message: 01/12/2005, 14h00
  3. Optimisation d'une requête patchwork
    Par ARRG dans le forum Langage SQL
    Réponses: 1
    Dernier message: 11/09/2005, 15h23
  4. optimisation d'une requête avec jointure
    Par champijulie dans le forum PostgreSQL
    Réponses: 8
    Dernier message: 07/07/2005, 09h45
  5. [DB2] Optimisation d'une requête
    Par ahoyeau dans le forum DB2
    Réponses: 7
    Dernier message: 11/03/2005, 17h54

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