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

PL/SQL Oracle Discussion :

Problème de performance avec une variable


Sujet :

PL/SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Novembre 2011
    Messages
    101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Novembre 2011
    Messages : 101
    Par défaut Problème de performance avec une variable
    Bonjour,

    Je fais face à un problème assez inattendu.

    Voici une partie de code.

    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
    DECLARE
        v_code      VARCHAR2 (24);
        v_count   NUMBER;
    BEGIN
        v_code := '4.1214';
     
        SELECT   COUNT ( * )
          INTO   v_count
           FROM   customer cu, contract ca, contract_status cgtf
         WHERE       cu.code LIKE v_code
                 AND ca.customer_id = cu.customer_id
                 AND ca.co_id = cgtf.co_id
                 AND ch_status IN ('a', 's');
     
        DBMS_OUTPUT.put_line (v_count);
    END;
    Et une copie de celui-ci, la seule différence se situe dans le fait que je n'utilise pas de variable, mais la valeur en brut dans 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
    13
    14
    15
    16
    DECLARE
        v_code      VARCHAR2 (24);
        v_count   NUMBER;
    BEGIN
        v_code := '4.1214';
     
        SELECT   COUNT ( * )
          INTO   v_count
           FROM   customer cu, contract ca, contract_status cgtf
         WHERE       cu.code LIKE '4.1214'
                 AND ca.customer_id = cu.customer_id
                 AND ca.co_id = cgtf.co_id
                 AND ch_status IN ('a', 's');
     
        DBMS_OUTPUT.put_line (v_count);
    END;
    Mon soucis est celui-ci. Pour la première requête, le temps d'exécution est de 119 sec, la seconde : 0.015 seconde.

    Sachant que cette requête est appelée dans une boucle pouvant aller jusque 30.000 codes, la différence de performance est énorme.

    (Notez, j'utilise un LIKE car normalement il y a '%' à la fin, mais je ne l'utilise pas pour l'exemple, le résultat est semblable et n'est donc pas en cause).

    Notez aussi que le type VARCHAR2(24) utilisé pour ma variable v_code est le même que celui défini dans la table Customer pour mon cu.code.

    Qu'est-ce qui peut causer cela? Quelle serait la solution pour garder autant de performance avec une variable?

    Un grand merci d'avance.

    Merci à vous.

  2. #2
    Membre extrêmement actif
    Avatar de islamov2000
    Homme Profil pro
    Ingénieur d'études & developpement en informatique
    Inscrit en
    Septembre 2007
    Messages
    814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Ingénieur d'études & developpement en informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2007
    Messages : 814
    Billets dans le blog
    6
    Par défaut
    ça mesemble un peu bizare;
    il y a une énorme différence.
    je te propose le SQL dynamique.DECLARE
    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
        v_code      VARCHAR2 (24);
        v_count   NUMBER;
        la_requete varchar2(500);
    BEGIN
        v_code := '4.1214';
     
    la_requete:='    SELECT   COUNT ( * )'||
           ' FROM   customer cu, contract ca, contract_status cgtf '||
         ' WHERE       cu.code LIKE ''' ||v_code ||''''||
                 ' AND ca.customer_id = cu.customer_id'||
                 ' AND ca.co_id = cgtf.co_id'||
                 ' AND ch_status IN (''a'', ''s'')'||;
     
                 execute immediate la_requete into v_count;
     
        DBMS_OUTPUT.put_line (v_count);
    END;

  3. #3
    Membre confirmé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Novembre 2011
    Messages
    101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Novembre 2011
    Messages : 101
    Par défaut
    Ha, super, merci.

    Oui, c'est étrange cette différence pour une requête semblable... :/


    Mais avec l'execute immediate, c'est parfait.

  4. #4
    Membre confirmé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Novembre 2011
    Messages
    101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Novembre 2011
    Messages : 101
    Par défaut
    Encore un petit soucis.

    Comme je disais, je dois ajouter un % pour mon LIKE.

    Mais j'obtiens ce message d'erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ORA-00911: invalid character
    Pour simplifier, j'obtiens également l'erreur avec ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    DECLARE
    v_test VARCHAR2(500);
    BEGIN
    v_test := 'SELECT * FROM CUSTOMER WHERE CUSTCODE LIKE 4.%';
    EXECUTE IMMEDIATE v_test;
    END;
    Et pas avec ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    DECLARE
    v_test VARCHAR2(500);
    BEGIN
    v_test := 'SELECT * FROM CUSTOMER WHERE CUSTCODE LIKE 4.';
    EXECUTE IMMEDIATE v_test;
    END;
    Merci.

  5. #5
    Membre extrêmement actif
    Avatar de islamov2000
    Homme Profil pro
    Ingénieur d'études & developpement en informatique
    Inscrit en
    Septembre 2007
    Messages
    814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Ingénieur d'études & developpement en informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2007
    Messages : 814
    Billets dans le blog
    6
    Par défaut
    quel est letype CUSTCODE

  6. #6
    Membre confirmé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Novembre 2011
    Messages
    101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Novembre 2011
    Messages : 101
    Par défaut
    C'est du VARCHAR2, effectivement...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    DECLARE
    v_test VARCHAR2(500);
    BEGIN
    v_test := 'SELECT * FROM CUSTOMER WHERE CUSTCODE LIKE ''4.%''';
    EXECUTE IMMEDIATE v_test;
    END;
    Hé bien, merci encore.

  7. #7
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 134
    Par défaut
    4. est une valeur numérique. L'interpréteur Oracle peut soit le convertir en chaine pour l'utiliser avec l'opérateur LIKE, soit remplacer l'opérateur LIKE par l'opérateur = puisqu'il n'y a pas de caractère générique à prendre en compte.

    4.% n'est pas compréhensible par l'interpréteur. Il faut dans ce cas déclarer une chaine et donc l'encadrer d'apostrophes : '4.%'.
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

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

Discussions similaires

  1. Problème de performance avec une regexp
    Par NicoV dans le forum Collection et Stream
    Réponses: 10
    Dernier message: 21/02/2008, 18h46
  2. Réponses: 3
    Dernier message: 06/05/2007, 20h11
  3. problème d'envoi d'une variable avec get
    Par ANISSS dans le forum Langage
    Réponses: 7
    Dernier message: 23/02/2007, 12h49
  4. [Javascript] problème avec une variable
    Par creatik dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 03/09/2006, 18h38
  5. Réponses: 2
    Dernier message: 14/05/2004, 14h32

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