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 :

Indexer QUE la valeur NULL d'une colonne [12c]


Sujet :

Administration 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 Indexer QUE la valeur NULL d'une colonne
    Bonjour,

    Pour des raisons d'étude sur les index Oracle, je voudrais créer un index MAIS qui n'indexe QUE la valeur NULL d'une colonne.
    Quel intérêt? Imaginons une table de 10 000 000 de rows avec seulement 100 rows avec Col10 à NULL et le reste des rows avec la valeur 1 (c'est juste un cas d'école).

    Si je fais un SELECT avec la clause WHERE Col10 IS NULL, Oracle fera un Full Table Scan extrêmement coûteux. Pour éviter cela, j'indexe non pas Col10, car les rows avec NULL seront absents, mais je crée un indexe composite sur (Col1, 1).
    Et là, cool, le plan d'exécution montre un prédicat d'accès IS NULL à ces rows via l'index et non pas un prédicat de filtre.

    Maintenant je voudrais indexer uniquement la valeur NULL. Pourquoi? Faire sauter un ou deux niveaux de branches donc rendre l'index plus désirable pour le CBO car plus rapide à parcourir et puis avoir un index plus léger pour RMAN et Datapump car réduit à 100 rows.

    J'ai donc voulu créer un index sur fonction : si col10 is null then return col10,1 sinon return null, null;
    Pb : ça ne passe pas, je me heurte à des contraintes PL/SQL; pour qu'une fonction retourne N valeurs il faut créer un type objet ou utiliser un array de deux valeurs (ce que j'arrive à faire). MAIS, ensuite, impossible de créer un index en se basant sur cette fonction...

    Voilà, si vous avez des idées je suis preneur
    Dans le "pire" des cas, où cela n'est pas possible, peut-être que créer une partition pour mes 100 rows serait une solution... à voir
    DBA Oracle
    Rédacteur du blog : dbaoraclesql.canalblog.com

  2. #2
    Expert éminent
    Avatar de pachot
    Homme Profil pro
    Developer Advocate YugabyteDB
    Inscrit en
    Novembre 2007
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Suisse

    Informations professionnelles :
    Activité : Developer Advocate YugabyteDB
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 821
    Points : 6 443
    Points
    6 443
    Billets dans le blog
    1
    Par défaut
    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
     
    create table demo as select rownum id, case when rownum>2 then 'X' end flag from xmltable('1 to 100000');
     
     
    alter table demo add flag_is_null char generated always as (case when flag is null then 'Y' end) virtual;
    create index demo_flag_is_null on demo(flag_is_null);
     
     
    exec dbms_stats.gather_table_stats('','DEMO');
     
     
    explain plan for select * from demo where flag_is_null='Y';
     
     
    select * from dbms_xplan.display();
    Franck Pachot - Developer Advocate Yugabyte 🚀 Base de Données distribuée, open source, compatible PostgreSQL
    🗣 twitter: @FranckPachot - 📝 blog: blog.pachot.net - 🎧 podcast en français : https://anchor.fm/franckpachot

  3. #3
    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
    Qu'est-ce que nous ferions sans toi Franck?
    Merci pour le retour, je regarde ça très vite
    DBA Oracle
    Rédacteur du blog : dbaoraclesql.canalblog.com

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

    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
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Ca marche pareil avec un index de fonction

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    CREATE OR REPLACE FUNCTION wmc_demo (p_flag IN VARCHAR2) RETURN VARCHAR2 DETERMINISTIC
    IS
    BEGIN
    	IF p_flag IS NULL THEN RETURN 'Y'; END IF;
      RETURN NULL;
    END;
     
    CREATE INDEX demo_flag_is_null2 ON demo(wmc_demo(flag));
     
    exec dbms_stats.gather_table_stats('','DEMO');
     
    SELECT * FROM demo WHERE wmc_demo(flag) = 'Y';
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT index_name, leaf_blocks, distinct_keys, num_rows FROM user_indexes WHERE table_name = 'DEMO'
     
    INDEX_NAME	LEAF_BLOCKS	DISTINCT_KEYS	NUM_ROWS
    DEMO_FLAG_IS_NULL	1	1	2
    DEMO_FLAG_IS_NULL2	1	1	2
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  5. #5
    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
    Merci McM, j'avais essayé de faire un index sur fonction mais... échec
    DBA Oracle
    Rédacteur du blog : dbaoraclesql.canalblog.com

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

    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
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Il faut déclarer la fonction en DETERMINISTIC obligatoirement.
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  7. #7
    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
    Oui, c'est ce que j'avais fait mais je voulais indexer la valeur NULL et pas Y.
    Résultat, je voulais créer une fonction qui retournait 2 valeurs : NULL et 1 pour les rows avec Col10 à NULL et, pour les rows avec col10 <> NULL, je retourne NULL, NULL ==> résultat, je pensais qu'Oracle me créerait un index composite sur fonction, mais échec, il ne veut pas.
    DBA Oracle
    Rédacteur du blog : dbaoraclesql.canalblog.com

  8. #8
    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 McM Voir le message
    Ca marche pareil avec un index de fonction

    ...
    La solution proposé par Pachot implique un index de fonction en fait.

  9. #9
    Expert éminent
    Avatar de pachot
    Homme Profil pro
    Developer Advocate YugabyteDB
    Inscrit en
    Novembre 2007
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Suisse

    Informations professionnelles :
    Activité : Developer Advocate YugabyteDB
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 821
    Points : 6 443
    Points
    6 443
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par mnitu Voir le message
    La solution proposé par Pachot implique un index de fonction en fait.
    Exact. Et l'avantage de la colonne virtuelle, c'est qu'on l'utilise dans la where clause sans le risque que le prédicat soit différent de ce qui est indexé.
    En fait, les index sur fonction créent une colonne virtuelle, donc autant la créer nous-mêmes avec un nom parlant et utilisable dans les requêtes.
    Franck Pachot - Developer Advocate Yugabyte 🚀 Base de Données distribuée, open source, compatible PostgreSQL
    🗣 twitter: @FranckPachot - 📝 blog: blog.pachot.net - 🎧 podcast en français : https://anchor.fm/franckpachot

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 10/06/2011, 10h51
  2. Insertion d'une valeur null pour une colonne
    Par bigggalll dans le forum Développement de jobs
    Réponses: 3
    Dernier message: 24/03/2010, 15h01
  3. Insérer la valeur NULL dans une colonne de type number
    Par cocoaparis dans le forum PL/SQL
    Réponses: 8
    Dernier message: 08/07/2009, 15h46
  4. insérer la valeur null dans une colonne
    Par loic20h28 dans le forum C#
    Réponses: 12
    Dernier message: 27/05/2009, 11h21
  5. Réponses: 2
    Dernier message: 26/01/2009, 15h38

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