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 et fonctions : ORA-01450


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite
    Profil pro
    Inscrit en
    Août 2008
    Messages
    861
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 861
    Par défaut Index et fonctions : ORA-01450
    Bonjour,

    J'essaie de créer un index sous Oracle 10g portant sur des fonctions de ce type :

    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 fonction1 (param VARCHAR2)
    RETURN VARCHAR2
    DETERMINISTIC
    IS
    	retour VARCHAR2(32);
    BEGIN
     
    	IF INSTR(param, '-') <> 0
    		THEN retour := substr(param, 1,INSTR(param, '-')-1);
    	ELSE
    		retour := param;
    	END IF;
     
    	RETURN lower(retour);
    END;
    La seconde fonction utilisée dans mon index est très similaire.

    J'ai une table TABLETEST ayant un champs1 et un champs2 de type VARCHAR2(32).

    Si je crée un index avec une seule fonction, ça passe.

    Lorsque j'essaie de créer un index sur cette table en utilisant deux fonctions, j'obtiens l'erreur suivante ORA-01450: longueur maximum de clé (6398) depassée.
    De ce que j'ai compris et cherché sur le net, je suis en théorie très loin de cette longueur maximum.

    J'ai essayé de remplacer le RETURN lower(retour) par RETURN SUBSTRB(lower(retour),1,32), ça ne change rien.

    Voici le code utilisé pour la création de l'index :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    CREATE INDEX IDX_TEST 
    ON TABLETEST
    (fonction1(champs1),fonction2(champs2));
    Quelqu'un aurait-il une idée? Quelque chose doit m'echapper...
    Merci d'avance.

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    En aparté : ça m'étonne que vous ayiez créé une fonction pour du code aussi trivial, vous pouvez faire une ou plusieurs colonnes virtuelles et les indexer.

    Sur le sujet : aucune idée

  3. #3
    Membre émérite
    Profil pro
    Inscrit en
    Août 2008
    Messages
    861
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 861
    Par défaut
    Oui, deux colonnes virtuelles auraient fait l'affaire.
    Malheureusement, il me semble que ça n'est disponible qu'a partir d'Oracle 11, or je travaille sur 10g.

    Soit dit en passant, si je remplace par des CASE ... WHEN dans mon index, ça fonctionne. Seulement, ça oblige à utiliser le même CASE dans les requetes, et cette table est utilisée pour en charger beaucoup d'autres. Si la chaine à extraire change, j'aimerai n'avoir à changer que la fonction, pas toutes les requetes et l'index.

  4. #4
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Vous pouvez envisager une vue peut-être.

  5. #5
    Membre émérite
    Profil pro
    Inscrit en
    Août 2008
    Messages
    861
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 861
    Par défaut
    Une vue materialisée? C'est une bonne idée, mais j'aurai préféré éviter, ou au moins comprendre pourquoi mon index ne veut pas passer.
    Merci pour tes suggestions

  6. #6
    Expert confirmé 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
    Par défaut
    Restrictions for Function-Based Indexes
    Function-based indexes cannot use expressions that return VARCHAR2 or RAW data types of unknown length from PL/SQL functions. A workaround is to limit the size of the function's output by indexing a substring of known length:

    -- INITIALS() might return 1 letter, 2 letters, 3 letters, and so on.
    -- We limit the return value to 10 characters for purposes of the index.
    CREATE INDEX func_substr_index ON
    emp_tab(substr(initials(ename),1,10);

    -- Call SUBSTR both when creating the index and when referencing
    -- the function in queries.
    SELECT SUBSTR(initials(ename),1,10) FROM emp_tab;
    Essaie donc comme ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    CREATE INDEX IDX_TEST 
    ON TABLETEST
    (SubStr(fonction1(champs1)1,32),SubStr(fonction2(champs2)1,32));

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 28/02/2008, 08h17
  2. Tuning requête et indexes sur fonction
    Par Mehdilis dans le forum Oracle
    Réponses: 3
    Dernier message: 26/02/2007, 13h36
  3. Requete group by et index sur fonction
    Par Omsey dans le forum Oracle
    Réponses: 8
    Dernier message: 26/10/2006, 10h26
  4. indexer uen fonction d'un DLL
    Par athos- dans le forum C++
    Réponses: 6
    Dernier message: 22/06/2006, 13h35
  5. index sur fonction
    Par Spoutnik dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 03/05/2006, 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