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

Administration Oracle Discussion :

Problème de performance/de plan


Sujet :

Administration Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    167
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 167
    Par défaut Problème de performance/de plan
    Bonjour a tous!
    Je souhaite executer une requête sur notre base Oracle 9i :

    select count(r.sigma) from rum_cafe ru, rss r where ru.flag = 'W' and ru.id_rum = r.id_rum
    Cette requête passe très bien, et très rapidement.
    En effet, il y a un index sur ru.flag ainsi que sur les champs id_rum sur les deux tables (primary key)...
    Temps d'exécution : 20sec...Résultat 3032 donc on est sur une faible volumétrie.

    Seulement, quand je veux ajouter un distinct :

    select count(distinct(r.sigma)) from rum_cafe ru, rss r where ru.flag = 'W' and ru.id_rum = r.id_rum
    Alors la c'est plus du tout la même chose...
    Temps d'exécution 20 min ! Résultat 1792...

    19 min de plus juste pour faire un distinct sur 3000 lignes, ca fait un peu beaucoup...

    J'ai donc sorti les deux plans d'exécution :



    PLAN_TABLE_OUTPUT

    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
    -------------------------------------------------------------------------
    | 0 | SELECT STATEMEN | | 1 | 20 | 1898 (1)|
    | 1 | SORT AGGREGATE | | 1 | 20 | |
    | 2 | NESTED LOOPS | | 48438 | 946K| 1898 (1)|
    |* 3 | TABLE ACCESS FULL| RUM_CAFE| 48438 | 520K| 1896 (0)|
    |* 4 | INDEX UNIQUE SCAN| PK_RSS | 1 | 9 | |
    -------------------------------------------------------------------------

    Predicate Information (identified by operation id):
    ---------------------------------------------------

    3 - filter("RU"."FLAG"='W')
    4 - access("RU"."ID_RUM"="R"."ID_RUM")
    Pour la même requête avec le distinct :

    PLAN_TABLE_OUTPUT

    | Id | Operation | Name | Rows | Bytes |TempSpc| Cost(%CPU)|
    ------------------------------------------------------------------------------------------
    | 0 | SELECT STATEMENT| | 1 | 26 | | 2682 (0)|
    | 1 | SORT GROUP BY | | 1 | 26 | | |
    | 2 | MERGE JOIN | | 48438|1229K | | 2682 (0)|
    | 3 |TABLE ACCESS BY INDEX ROWID| RSS |2164K| 30M| | 207 (0)|
    | 4 | INDEX FULL SCAN | PK_RSS|2164K| | | 26 (0)|
    |* 5 | SORT JOIN | | 48438 | 520K| 1922K| 2475 (0)|
    |* 6 | TABLE ACCESS FULL| RUM_CAFE | 48438 | 520K| | 1896 (0)|
    ------------------------------------------------------------------------------------------

    Predicate Information (identified by operation id):
    ---------------------------------------------------

    5 - access("RU"."ID_RUM"="R"."ID_RUM")
    filter("RU"."ID_RUM"="R"."ID_RUM")
    6 - filter("RU"."FLAG"='W')

    19 ligne(s) sélectionnée(s).
    Voila, donc j'ai bien l'impression que mon Oracle se plante dans le plan...
    En effet, au lieu de faire le distinct juste sur les lignes issues de la jointure et des clauses...(ce qui fais qu'il ne fais le distinct que sur 3000 lignes) j'ai l'impression qu'il fais le distinct sur ma table complète (table rum de 2 millions de lignes), qu'ils fais la projection du coté rum_cafe, et qu'il fais un join entre les deux....

    Comment faire pour contourner ce problème...

    J'ai testé aussi avec d'autres types de requêtes :
    select distinct sigma from rss where id_rum in (select id_rum from rum_cafe where flag='W');
    select r.sigma from rum_cafe ru, rss r where ru.flag = 'W' and ru.id_rum = r.id_rum group by sigma
    sans succès, toujours plus de 20 min...

    Si quelqu'un a une idée, je suis preneur et je vous remercie tous d'avance.

  2. #2
    Membre Expert Avatar de Garuda
    Homme Profil pro
    Chef de projet / Urbaniste SI
    Inscrit en
    Juin 2007
    Messages
    1 285
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Chef de projet / Urbaniste SI
    Secteur : Bâtiment

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 285
    Par défaut
    Essaye
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    select count(distinct(r.sigma)) from rum_cafe ru
    where exists (select 1 from
     rss r where ru.flag = 'W' and ru.id_rum = r.id_rum)

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    167
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 167
    Par défaut
    Ben ca me fais la même chose, toujours 20min...
    Je vais regarder du coté de l'analyse d'Oracle...(requête analyse de base)

    Mais merci quand même!

  4. #4
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    Dans ton premier plan il ne prend pas l'index sur FLAG.
    Le count(sigma) te renvoie le nb de sigma renseignés (différent de count(*))

    J'ai pas trop d'idée pourquoi le plan change avec le distinct

    Que donne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    select count(*)
    from rum_cafe ru, rss r 
    where ru.flag = 'W' 
    and ru.id_rum = r.id_rum 
    and sigma IS NULL

  5. #5
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par Garuda
    Essaye
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    select count(distinct(r.sigma)) 
    from rum_cafe ru
    where exists (select 1 from
     rss r where ru.flag = 'W' and ru.id_rum = r.id_rum)
    Voila pourquoi j'avais fait une erreur : Sigma est sur la table rss
    Elle peut pas marcher cette requete !

  6. #6
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    C'est pô bien le In sur des tables de 2000000 de lignes
    Vérifie le plan des 2 requetes (et le temps d'exec)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT DISTINCT sigma 
    FROM rss 
    WHERE id_rum IN (SELECT id_rum FROM rum_cafe WHERE flag='W');
    =>
    SELECT DISTINCT sigma 
    FROM rss r
    WHERE EXISTS (SELECT 1 FROM rum_cafe c
    		WHERE c.flag='W'
    		AND c.id_rum = r.id_rum)

  7. #7
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    et pourquoi pas simplement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT DISTINCT sigma 
    FROM rss , rum_cafe
    WHERE rss.id_rum = rum_cafe.id_rum 
        AND flag='W'
    et une bonne fois pour toute, EXIST n'est pas forcément plus performant, ça dépend de l'échantillon de données

    EDIT : j'aurais mieux fait de lire le 1° post

    Alors le problème est clair, les 19 minutes de plus viennent du DISTINCT. Ce DISTINCT fait du tri... on peut donc en conclure, que le problème ne vient pas de la requête mais des paramètres de tri

    Je te conseille un index sur les colonnes id_rum et sigma de rss pour facilité le tri et surtout éviter un TABLE ACCESS

Discussions similaires

  1. Problème de performance avec LEFT OUTER JOIN
    Par jgfa9 dans le forum Requêtes
    Réponses: 6
    Dernier message: 17/07/2005, 13h17
  2. [jeu]problème de performance d'un algo
    Par le Daoud dans le forum Algorithmes et structures de données
    Réponses: 12
    Dernier message: 30/05/2005, 16h07
  3. [C#] Probléme de performance avec IsDbNull
    Par jab dans le forum Windows Forms
    Réponses: 8
    Dernier message: 04/04/2005, 11h39
  4. [oracle 9i][Workbench]Problème de performance
    Par nuke_y dans le forum Oracle
    Réponses: 6
    Dernier message: 03/02/2005, 17h38
  5. [ POSTGRESQL ] Problème de performance
    Par Djouls64 dans le forum PostgreSQL
    Réponses: 6
    Dernier message: 26/05/2003, 16h18

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