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 :

Index non utilisé dans une requête


Sujet :

Administration Oracle

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    461
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 461
    Points : 283
    Points
    283
    Par défaut Index non utilisé dans une requête
    Bonjour,
    J'ai une requête utilisant une fonction (voir plus bas). Afin d'améliorer les performances, j'ai ajouter un indexe basé sur cette fonction, mais le moteur Oracle ne l'utilise pas, et lorsque je force l'utilisation de cet indexe via un HINT, je vois que le moteur Oracle a raison mais ne comprend pas. Voici le détail :
    Voici le 1er plan :
    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
    16
    17
    18
    19
    20
    21
    22
    explain plan for SELECT
      NVL(DOSSIER,'VIDE' ) AS T1
    FROM
      MA_TABLE
    GROUP BY
       NVL(DOSSIER,'VIDE')
    ORDER BY
       T1 ASC;
     
     
    PLAN_TABLE_OUTPUT
    ------------------------------------------------------------------------------------------------------
    Plan hash value: 4111865712
     
    --------------------------------------------------------------------------------------------------
    | Id  | Operation           | Name                       | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT    |                            |   364 |  2912 | 13002  (10)| 00:02:37 |
    |   1 |  SORT ORDER BY      |                            |   364 |  2912 | 13002  (10)| 00:02:37 |
    |   2 |   HASH GROUP BY     |                            |   364 |  2912 | 13002  (10)| 00:02:37 |
    |   3 |    TABLE ACCESS FULL| MA_TABLE                   |  2235K|    17M| 12256   (4)| 00:02:28 |
    --------------------------------------------------------------------------------------------------
    Second plan avec HINT sur l'indexe de fonction :
    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
    16
    17
    18
    19
    20
    21
    explain plan for SELECT /*+ INDEX(MA_TABLE IDX_NVL_MA_TABLE_ASC) */
      NVL(DOSSIER,'VIDE' ) AS T1
    FROM
      MA_TABLE
    GROUP BY
       NVL(DOSSIER,'VIDE')
    ORDER BY
       T1 ASC;
     
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------------------------
    Plan hash value: 1625393906
     
    ------------------------------------------------------------------------------------------------
    | Id  | Operation             | Name                   | Rows  | Bytes | Cost (%CPU)| Time     |
    ------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT      |                        |   364 |  2912 |   373K  (1)| 01:14:48 |
    |   1 |  SORT ORDER BY        |                        |   364 |  2912 |   373K  (1)| 01:14:48 |
    |   2 |   SORT GROUP BY NOSORT|                        |   364 |  2912 |   373K  (1)| 01:14:48 |
    |   3 |    INDEX FULL SCAN    | IDX_NVL_MA_TABLE_ASC   |  2193K|       |  6773   (2)| 00:01:22 |
    ------------------------------------------------------------------------------------------------
    De plus, mon indexe de fonction est déja trié.
    Vu que je ne souhaite obtenir que les informations d'un colonne et que cette dernière est indexée, pourquoi Oracle ne l'utilise pas et pourquoi ce plan qui prend 1h12' de plus ?

    Ps : taille de la table 472 Mo et 60 416 blocks
    taille de l'indexe 56 Mo et 7 168 blocks

    Merci d'avance pour votre aide.

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Qu'est-ce que ça donne avec cette requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT DISTINCT NVL(DOSSIER,'VIDE' ) AS T1
      FROM MA_TABLE;

  3. #3
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Si vous examinez les deux plans il est facile de voir que la principale différence est donnée par la méthode utilisé pour l'agrégation: SORT GROUP BY (NOSORT) vs HASH GROUP BY.

  4. #4
    Membre actif
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    461
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 461
    Points : 283
    Points
    283
    Par défaut
    Bonjour,

    Waldar, voici le résultat de la requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT DISTINCT NVL(DOSSIER,'VIDE' ) AS T1
      FROM MA_TABLE;
    T1
    --------------------
    TOTO
    TATA
    TITI
    .
    VIDE
    .
    .
    967 ligne(s) sÚlectionnÚe(s).
    Mnitu :

    Si vous examinez les deux plans il est facile de voir que la principale différence est donnée par la méthode utilisé pour l'agrégation: SORT GROUP BY (NOSORT) vs HASH GROUP BY.
    Oui, ça je l'ai bien vu mais ça ne m'explique pas, ni le choix, ni le chiffrage de l'optimiseur.

    D'ailleurs, j'ai relancé la requête avec le HINT en la traçant. Et curieusement, le résultat n'est pas du tout celui prédit par Voici le résultat de la trace dans TKPROF :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    call     count       cpu    elapsed       disk      query    current        rows
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    Parse        1      0.01       0.01          0          0          0           0
    Execute      1      0.00       0.00          0          0          0           0
    Fetch       66      2.36       5.83       6683       6683          0         967
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    total       68      2.38       5.84       6683       6683          0         967
    Quelqu'un peut t'il m'expliquer pourquoi la prévision de l'optimiseur est à ce point erronnée ?

  5. #5
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Citation Envoyé par tibal Voir le message
    Waldar, voici le résultat de la requête :
    Je parlais de l'explain plan et du temps d'exécution bien sûr

  6. #6
    Membre actif
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    461
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 461
    Points : 283
    Points
    283
    Par défaut
    Voici Waldar :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    explain plan for 
    SELECT DISTINCT NVL(DOSSIER,'VIDE' ) AS T1
      FROM MA_TABLE;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------------------------
    Plan hash value: 2166119174
     
    --------------------------------------------------------------------------------------------------
    | Id  | Operation               | Name                   | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT        |                        |  2193K|    16M|  1520   (4)| 00:00:19 |
    |   1 |  PX COORDINATOR         |                        |       |       |            |          |
    |   2 |   PX SEND QC (RANDOM)   | :TQ10000               |  2193K|    16M|  1520   (4)| 00:00:19 |
    |   3 |    PX BLOCK ITERATOR    |                        |  2193K|    16M|  1520   (4)| 00:00:19 |
    |   4 |     INDEX FAST FULL SCAN| IDX_NVL_MA_TABLE_ASC   |  2193K|    16M|  1520   (4)| 00:00:19 |
    --------------------------------------------------------------------------------------------------

  7. #7
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Citation Envoyé par tibal Voir le message
    ...
    Mnitu :

    Oui, ça je l'ai bien vu mais ça ne m'explique pas, ni le choix, ni le chiffrage de l'optimiseur.
    Si vous voulez plus des informations tracer l'optimiseur via l'événement 10053.

    Citation Envoyé par tibal Voir le message
    ...
    ...
    D'ailleurs, j'ai relancé la requête avec le HINT en la traçant. Et curieusement, le résultat n'est pas du tout celui prédit par EXPLAIN PLAN FOR ...

    Quelqu'un peut t'il m'expliquer pourquoi la prévision de l'optimiseur est à ce point erronnée ?
    Le plan ne dépend pas seulement de la requête mais aussi de pas mal des autres choses: les paramètres de la session, les statistiques, etc.

  8. #8
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Tibal, ok, mais il faut en tirer les conclusions !
    L'explain plan paraît bien, il utilise l'index et il n'y a pas besoin de hint.

    La conclusion c'est qu'une requête correctement écrite est meilleure qu'une requête mal écrite.
    Utiliser group by pour faire un distinct, c'est très rarement justifiable !

  9. #9
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Il ne faut pas non plus tirer trop vite des conclusions (mais, je suis tout à fait d'accord Waldar avec ta remarque). Que est-ce que ça donne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    EXPLAIN plan FOR 
    SELECT DISTINCT NVL(DOSSIER,'VIDE' ) AS T1
      FROM MA_TABLE
    ORDER BY T1

  10. #10
    Membre actif
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    461
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 461
    Points : 283
    Points
    283
    Par défaut
    Waldar :

    Tibal, ok, mais il faut en tirer les conclusions !
    L'explain plan paraît bien, il utilise l'index et il n'y a pas besoin de hint.
    Oui, mais pas dans la requête initiale, et c'est celle-ci qui est importante.

    La conclusion c'est qu'une requête correctement écrite est meilleure qu'une requête mal écrite.
    Je n'ai pas la main, c'est un applicatif client qui en est à l'origine.

    Utiliser group by pour faire un distinct, c'est très rarement justifiable !
    Il n'y a pas de group by et un distinct dans ma requête initiale.

    Mnitu, voici le résulta demandé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    EXPLAIN plan FOR 
    SELECT DISTINCT NVL(DOSSIER,'VIDE' ) AS T1
      FROM MA_TABLE
    ORDER BY T1
    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
    16
    PLAN_TABLE_OUTPUT
    ---------------------------------------------------------------------------------------------------------------------
    Plan hash value: 3763606681
     
    -------------------------------------------------------------------------------------------------------------
    | Id  | Operation                  | Name                   | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
    -------------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT           |                        |  2193K|    16M|       |  9797   (5)| 00:01:58 |
    |   1 |  PX COORDINATOR            |                        |       |       |       |            |       |
    |   2 |   PX SEND QC (ORDER)       | :TQ10001               |  2193K|    16M|       |  9797   (5)| 00:01:58 |
    |   3 |    SORT ORDER BY           |                        |  2193K|    16M|    67M|  9797   (5)| 00:01:58 |
    |   4 |     PX RECEIVE             |                        |  2193K|    16M|       |  1520   (4)| 00:00:19 |
    |   5 |      PX SEND RANGE         | :TQ10000               |  2193K|    16M|       |  1520   (4)| 00:00:19 |
    |   6 |       PX BLOCK ITERATOR    |                        |  2193K|    16M|       |  1520   (4)| 00:00:19 |
    |   7 |        INDEX FAST FULL SCAN| IDX_T_DOSSIER_USER_ASC |  2193K|    16M|       |  1520   (4)| 00:00:19 |
    -------------------------------------------------------------------------------------------------------------
    Merci encore à tous les deux.

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

Discussions similaires

  1. Index non utilisé dans une jointure
    Par lasyan3 dans le forum SQL
    Réponses: 15
    Dernier message: 12/04/2011, 09h06
  2. Résultat de Checkbox utilisé dans une requête
    Par anthony_rexis dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 24/07/2007, 09h43
  3. Valeur non trouvé dans une requète SQL
    Par Jeankiki dans le forum Bases de données
    Réponses: 2
    Dernier message: 15/12/2006, 16h36
  4. variable non reconnue dans une requête sql
    Par sanatou dans le forum C++
    Réponses: 3
    Dernier message: 13/12/2006, 17h43
  5. champs non accessibles dans une requête sélection
    Par Claire31 dans le forum Requêtes et SQL.
    Réponses: 8
    Dernier message: 03/08/2006, 13h22

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