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 :

Index partiel simulé sous Oracle avec une fonction : utilisation avec un hint impossible


Sujet :

SQL Oracle

  1. #1
    Membre émérite
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Avril 2013
    Messages
    1 993
    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 : 1 993
    Points : 2 499
    Points
    2 499
    Par défaut Index partiel simulé sous Oracle avec une fonction : utilisation avec un hint impossible
    Hello tout le monde,

    J'ai voulu créer un index partiel sous Oracle même si je sais qu'Oracle ne le fais pas en standard (sauf pour les attributs NULL où là les rows avec cet attribut à Null ne sont pas indexés).

    J'ai créé la fonction suivante qui retourne 80 pour les enregistrements avec le champ EMPLOYEES.DEPARTMENT_ID à 80 et NULL sinon.
    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
    CREATE OR REPLACE FUNCTION F_dpt_id_80(p_dpt_id EMPLOYEES.DEPARTMENT_ID%TYPE)
    RETURN EMPLOYEES.DEPARTMENT_ID%TYPE 
    DETERMINISTIC 
    IS
    BEGIN
    	IF p_dpt_id = 80 THEN
    		return p_dpt_id;
    	ELSE
    		return NULL;
    	END IF;
     
    EXCEPTION
    	WHEN OTHERS THEN
    	NULL;
    END;
    /
    Ensuite je crée un index sur cette fonction.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    create index EMP_DPT_ID_80 ON EMPLOYEES(F_dpt_id_80(department_id));
    Dans ALL_INDEXES j'ai le bon nombre d'enregs, à savoir 34, ce qui correspond bien au nombre d'enregs avec la valeur 80 donc j'ai un index partiel sur la valeur indexée EMPLOYEES.DEPARTMENT_ID.

    Là où ça coince c'est qu'Oracle refuse d'utiliser cet index même si j'utilise un hint :calim2.
    Je précise que j'ai validé la syntaxe de l'emploi du hint en utilisant un autre ordre SQL avec un autre index ou même en mettant INDEX en minuscules.
    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    SQL> select /*+ INDEX(EMPLOYEES EMP_DPT_ID_80) */ first_name from employees where department_id =80;
    
    FIRST_NAME
    --------------------
    John
    Karen
    Alberto
    Gerald
    Eleni
    Peter
    David
    Peter
    Christopher
    Nanette
    Oliver
    
    FIRST_NAME
    --------------------
    Janette
    Patrick
    Allan
    Lindsey
    Louise
    Sarath
    Clara
    Danielle
    Mattea
    David
    Sundar
    
    FIRST_NAME
    --------------------
    Amit
    Lisa
    Harrison
    Tayler
    William
    Elizabeth
    Sundita
    Ellen
    Alyssa
    Jonathon
    Jack
    
    FIRST_NAME
    --------------------
    Charles
    
    34 rows selected.
    
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 1445457117
    
    -------------------------------------------------------------------------------
    | Id  | Operation         | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
    -------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |           |    10 |   100 |     3   (0)| 00:00:01 |
    |*  1 |  TABLE ACCESS FULL| EMPLOYEES |    10 |   100 |     3   (0)| 00:00:01 |
    -------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - filter("DEPARTMENT_ID"=80)
    
    
    Statistics
    ----------------------------------------------------------
              8  recursive calls
              0  db block gets
             11  consistent gets
              0  physical reads
              0  redo size
           1279  bytes sent via SQL*Net to client
            545  bytes received via SQL*Net from client
              4  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
             34  rows processed

    Donc mon index existe MAIS Oracle refuse de l'utiliser...
    Si vous pouviez me dire pourquoi, un grand merci par avance
    DBA Oracle
    Rédacteur du blog : dbaoraclesql.canalblog.com

  2. #2
    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
    Ca marche sans aucun hint sql mais il y a mieux à faire. Et supprimez vite le bloc d'exception qui est un vrai bug dans ce cas.

    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
    23
    24
    25
     
    SQL> explain plan for
      2  
      2  select first_name
      3    from hr.employees e
      4   where F_dpt_id_80(department_id) = 80
      5  /
    Explained
     
    SQL> select * from table(dbms_xplan.display)
      3  /
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------
    Plan hash value: 312955501
    --------------------------------------------------------------------------------
    | Id  | Operation                   | Name          | Rows  | Bytes | Cost (%CPU
    --------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |               |     1 |    20 |     2   (0
    |   1 |  TABLE ACCESS BY INDEX ROWID| EMPLOYEES     |     1 |    20 |     2   (0
    |*  2 |   INDEX RANGE SCAN          | EMP_DPT_ID_80 |     1 |       |     1   (0
    --------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       2 - access("HR"."F_DPT_ID_80"("DEPARTMENT_ID")=80)
    14 rows selected

  3. #3
    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 Ikebukuro Voir le message
    Donc mon index existe MAIS Oracle refuse de l'utiliser...
    Parce que vous n'utilisez pas la fonction dans votre requête, cf. l'exemple de mnitu.

  4. #4
    Membre émérite
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Avril 2013
    Messages
    1 993
    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 : 1 993
    Points : 2 499
    Points
    2 499
    Par défaut
    OUF, un gros merci pour vos réponses car je m'arrachais mes quelques rares cheveux :-)
    Finalement c'était juste une erreur bête de ma part

    mnitu, quand tu dis "qu'il y a mieux à faire", tu penses à quoi?
    DBA Oracle
    Rédacteur du blog : dbaoraclesql.canalblog.com

  5. #5
    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 Ikebukuro Voir le message
    ...
    mnitu, quand tu dis "qu'il y a mieux à faire", tu penses à quoi?
    LA fonction en question peut être remplacée par un simple Case mais bon comme j'imagine que c'est juste un test pour comprendre que ça marche cela n'a pas finalement d'importance.

Discussions similaires

  1. [AJAX] Liens chargés avec une fonction Ajax
    Par MrPiMs dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 10/03/2009, 16h19
  2. Onclick avec une fonction utilisant $(this)
    Par Calvein dans le forum jQuery
    Réponses: 5
    Dernier message: 20/01/2009, 16h04
  3. Réponses: 8
    Dernier message: 23/02/2008, 09h49
  4. Définir une "Public Const" avec une fonction
    Par bernardmichel dans le forum VBA Access
    Réponses: 6
    Dernier message: 29/09/2007, 15h16
  5. Problème avec une Fonction utilisant WMI
    Par Eric_78180 dans le forum VBScript
    Réponses: 3
    Dernier message: 29/12/2006, 14h00

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