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 :

[optimisation] vue ou fonction ?


Sujet :

SQL Oracle

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    111
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2007
    Messages : 111
    Points : 56
    Points
    56
    Par défaut [optimisation] vue ou fonction ?
    Bonjour,

    je suis en train de parcourir un projet. Et j'ai vu qu'une même opération était réalisée de deux façons différentes. Par soucis de clarté, j'aimerais n'utiliser qu'une seule méthode. Afin d'opter pour la bonne méthode, j'aimerais savoir si une de ces deux méthodes est meilleure que l'autre, et si oui pourquoi.

    Voici la situation.

    Une table 'codes' contient trois colonnes : id_category, id_code, name.

    Une catégorie contient plusieurs codes. Au sein d'une catégorie, à chaque id_code correspond un name.

    Le name correspondant à une paire <id_category ; id_code> doit être inséré dans d'autres tables. Actuellement deux méthodes sont utilisées.

    1ère méthode: Vue

    Une vue (non matérialisée) est crée pour chaque catégorie :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CREATE OR REPLACE FORCE VIEW v_category_1 (id_code, name)
    AS
        SELECT id_code, name
        FROM codes
        WHERE id_category = 'CAT1';
    Ensuite lors de l'insertion dans la table finale, on réalise une jointure (selon cette méthode : http://blog.developpez.com/sqlpro?ti..._dans_le_from_) entre la vue et une table d'input contenant également un id_code. A noter qu'on insère tout le contenu de la table d'input en une seule opération.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    INSERT INTO final_table
    SELECT name from v_category_1 
       JOIN input_table 
       ON v_category_1.id_code = input_table.id_code
    2ème méthode: Fonction

    Une fonction valide pour toutes les catégories de code a été créée (-> avantage pour la maintenance mais ce n'est pas le sujet de ma question ).

    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
    CREATE OR REPLACE FUNCTION FUNC_CODES (InFielD VARCHAR2,InValue VARCHAR2)
    RETURN VARCHAR2
    IS
     
        OutValue codes.name%type;
     
    BEGIN
     
        OutValue := null;
     
        select  name
                into    OutValue
                from    codes
                where   upper(rtrim(id_category)) = upper(rtrim(InField)) and
                        upper(trim(id_code)) = upper(rtrim(InValue));
     
        RETURN OutValue;
    END FUNC_CODES;
    Et dans ce cas, la requête d'insertion ressemble à :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    INSERT INTO final_table
    SELECT func_codes('CAT1', id_code)
    FROM input_table
    Ma question est donc, quelle est la méthode offrant le meilleur niveau de performance, sachant que les input_table peuvent contenir jusqu'à quelques millions de records ? Bien sûr, quelques explications justificatives sont les bienvenues.

    D'avance, je vous remercie.

  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
    La deuxième n'est pas une solution mais un problème qui attends de se faire remarquer. Je veux revenir plus tard.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    111
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2007
    Messages : 111
    Points : 56
    Points
    56
    Par défaut
    Citation Envoyé par mnitu Voir le message
    La deuxième n'est pas une solution mais un problème qui attends de se faire remarquer. Je veux revenir plus tard.
    J'attends votre retour avec impatience

  4. #4
    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
    La fonction sera appellée itérativement par oracle, pour résumer les lignes seront parcourues une par une, et niveau perf ce sera très probablement mauvais.

    L'insertion ensembliste en utilisant la vue est le meilleur, par contre l'intérêt de cette dernière me paraît limité.

    La requête suivante n'est pas complexe, néanmoins je ne connais pas tous les contextes métiers et celà peut avoir une justification quelconque.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    INSERT INTO final_table
    SELECT c.name
    FROM codes c JOIN input_table i ON c.id_code = i.id_code
    WHERE c.id_category = 'CAT1'
    Avec un index sur codes(id_category) et un autre sur input_table(id_code), si la volumétrie à filtrer est significative.

    Ah oui et j'espère que la requête est simplifiée pour le forum, car dupliquer n fois l'information name de la table de référence me paraît inutile !

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    111
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2007
    Messages : 111
    Points : 56
    Points
    56
    Par défaut
    Citation Envoyé par Waldar Voir le message
    La fonction sera appellée itérativement par oracle, pour résumer les lignes seront parcourues une par une, et niveau perf ce sera très probablement mauvais.
    Le seul moyen d'avoir une mesure de la différence de performance est-il d'utiliser tkprof ?

    Citation Envoyé par Waldar Voir le message
    L'insertion ensembliste en utilisant la vue est le meilleur, par contre l'intérêt de cette dernière me paraît limité.
    En effet, je me pose la même question. Il doit y avoir une raison historique à ce choix. Je vais investiguer. Sinon, j'utiliserais une requête similaire à celle que tu as proposée.

  6. #6
    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 brolon Voir le message
    Le seul moyen d'avoir une mesure de la différence de performance est-il d'utiliser tkprof ?
    ...
    Il y en a des autres. Pour exemple run_stats_pkg que tu peux chercher sur AskTom. Il est très bon pour comparer deux solutions différentes.

Discussions similaires

  1. [Struts] - Charger une vue en fonction du navigateur ?
    Par Tigrou35 dans le forum Struts 1
    Réponses: 1
    Dernier message: 07/08/2007, 11h58
  2. Réponses: 6
    Dernier message: 27/06/2007, 16h44
  3. Réponses: 5
    Dernier message: 20/06/2007, 15h21
  4. Réponses: 9
    Dernier message: 20/03/2007, 19h56
  5. Réponses: 3
    Dernier message: 07/09/2006, 12h00

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