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 :

améliorer perf d'une requête


Sujet :

PL/SQL Oracle

  1. #1
    Membre du Club
    Inscrit en
    Juin 2007
    Messages
    284
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 284
    Points : 66
    Points
    66
    Par défaut améliorer perf d'une requête
    Bonjour,

    je travaille avec oracle 10g. j'ai des pb de perf sur une requête.
    Voici ce que je fais :
    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
     
    OPEN c_curseur FOR SELECT DISTINCT 
                             r.chp1 ||
                             ';'            ||
                             r.chp2         ||
                             ';'                
                        FROM tab1 r
                        WHERE chp1= 'toto';
     
    LOOP 
            FETCH c_curseur
            INTO v_ligne;
            EXIT WHEN c_curseur%NOTFOUND;
     
            val_return := val_return || v_ligne || chr(10);
     
     
     END LOOP;
    Le Select dure qq secondes mais la boucle dure vers les 25 min pour 7000 lignes traitées.

    Comment je peux l'optimiser ?

    merci

  2. #2
    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
    Quel est l'intérêt de tout mettre dans une seule variable ?
    Je veux dire, qu'en faites-vous par la suite ?

  3. #3
    Membre du Club
    Inscrit en
    Juin 2007
    Messages
    284
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 284
    Points : 66
    Points
    66
    Par défaut
    la variable retour de ma fonction de type clob.

  4. #4
    Expert confirmé
    Avatar de laurentschneider
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Décembre 2005
    Messages
    2 944
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2005
    Messages : 2 944
    Points : 4 926
    Points
    4 926
    Par défaut
    tu as tenté un BULK COLLECT ?

  5. #5
    Membre du Club
    Inscrit en
    Juin 2007
    Messages
    284
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 284
    Points : 66
    Points
    66
    Par défaut
    J'ai essayé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    LOOP 
            FETCH c_curseur BULK COLLECT
            INTO v_ligne LIMIT 100;
            EXIT WHEN c_curseur%NOTFOUND;
     
            val_return := val_return || v_ligne || chr(10);
     
     
     END LOOP;
    mais j'ai le msg d'erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    PLS-00497: impossible de mélanger des clauses mono- et multi-lignes (BULK) da
    v_ligne es tde type VARCHAR2(255)
    ...????

  6. #6
    Membre expérimenté Avatar de ojo77
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Décembre 2010
    Messages
    680
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2010
    Messages : 680
    Points : 1 597
    Points
    1 597
    Par défaut
    Il doit manquer quelques infos

    J'ai fait le test suivant

    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
    EXEC SYS.DBMS_RANDOM.SEED(0);
     
    create table big_table (c1 NUMBER , c2 NUMBER , c3 VARCHAR2(10), c4 date );
     
    INSERT /*+ APPEND */ INTO big_table
    SELECT LEVEL c1,
           ROUND(SYS.DBMS_RANDOM.NORMAL) c2,
           SYS.DBMS_RANDOM.STRING('x',10) c3,
           sysdate+ROUND(SYS.DBMS_RANDOM.NORMAL) c4
      FROM DUAL
    CONNECT BY LEVEL <= 1e6;
     
    COMMIT;
     
     
    create or replace function aggr return clob is
      ttext varchar2(32767);
      ret   clob;
    begin
      ret:='col1;col2
    ';
      for c in (select c1
                     , c2 
                     , c3
                from big_table
    			where c2=0)
      loop
        ttext:=trim(to_char(c.c1))||';'||trim(to_char(c.c2))||';'||c.c3||';
    ';
        dbms_lob.writeappend(ret,length(ttext),ttext);
      end loop;
      return ret;
    end;
    /
    J'ai donc une table de 1 million de lignes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SQL> select count(*) from big_table where c2=0;
     
      COUNT(*)
    ----------
        382462
     
    EcoulÚ : 00 :00 :00.10
    J'ai 382 462 lignes pour c2=0. Je lance ma fonction avec timing on et autotrace en mode traceonly :

    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
    SQL> select aggr() from dual;
     
    EcoulÚ : 00 :00 :10.53
     
    Plan d'exÚcution
    ----------------------------------------------------------
    Plan hash value: 1388734953
     
    -----------------------------------------------------------------
    | Id  | Operation        | Name | Rows  | Cost (%CPU)| Time     |
    -----------------------------------------------------------------
    |   0 | SELECT STATEMENT |      |     1 |     2   (0)| 00:00:01 |
    |   1 |  FAST DUAL       |      |     1 |     2   (0)| 00:00:01 |
    -----------------------------------------------------------------
     
     
    Statistiques
    ----------------------------------------------------------
           3864  recursive calls
        2314071  db block gets
         390696  consistent gets
              0  physical reads
              0  redo size
           1014  bytes sent via SQL*Net to client
            716  bytes received via SQL*Net from client
              5  SQL*Net roundtrips to/from client
              1  sorts (memory)
              0  sorts (disk)
              1  rows processed
    J'execute le tout en 10 secondes environ on est loin de 25 minutes pour 17 000 lignes ...

  7. #7
    Membre du Club
    Inscrit en
    Juin 2007
    Messages
    284
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 284
    Points : 66
    Points
    66
    Par défaut
    je ne comprends pas...

  8. #8
    Membre expérimenté Avatar de ojo77
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Décembre 2010
    Messages
    680
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2010
    Messages : 680
    Points : 1 597
    Points
    1 597
    Par défaut
    Pouvez vous lancez la fonction avec une trace 10046 afin d'analyser ou le tempos est perdu et poster le tkprof ?

  9. #9
    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
    C'est la réaffectation du CLOB qui est super longue.
    Suivant la taille de tes 2 champs, tu peux concatener dans un VARCHAR2(32768) et tous les X loop, tu concatènes la chaine au CLOB.
    Ou faire du dbms_lob.append, tu peux te baser sur ce post : http://www.developpez.net/forums/d10...ess-decriture/
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

Discussions similaires

  1. cherche aide pour améliorer le traitement d'une requête
    Par nomade333 dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 22/04/2008, 14h15
  2. Pb de perfs pour une requête
    Par marman dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 27/11/2006, 13h22
  3. Amélioration d'une requête
    Par phtpht dans le forum Langage SQL
    Réponses: 3
    Dernier message: 27/07/2006, 12h20
  4. améliorer une requête
    Par papilou86 dans le forum Access
    Réponses: 5
    Dernier message: 22/05/2006, 11h40
  5. Réponses: 4
    Dernier message: 12/12/2005, 17h25

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