Précédent   Forum des professionnels en informatique > Bases de données > Oracle > PL/SQL
PL/SQL Forum d'entraide sur le PL/SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 04/04/2011, 17h49   #1
Nouveau Membre du Club
 
Inscription : juin 2007
Messages : 271
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 271
Points : 32
Points : 32
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 :
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
ouinih est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/04/2011, 18h20   #2
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 684
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 684
Points : 10 442
Points : 10 442
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Quel est l'intérêt de tout mettre dans une seule variable ?
Je veux dire, qu'en faites-vous par la suite ?
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/04/2011, 18h24   #3
Nouveau Membre du Club
 
Inscription : juin 2007
Messages : 271
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 271
Points : 32
Points : 32
la variable retour de ma fonction de type clob.
ouinih est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 05/04/2011, 09h49   #4
Expert Confirmé Sénior


 
Avatar de laurentschneider
 
Homme Laurent Schneider
Administrateur de base de données
Inscription : décembre 2005
Messages : 2 925
Détails du profil
Informations personnelles :
Nom : Homme Laurent Schneider
Localisation : Suisse

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

Informations forums :
Inscription : décembre 2005
Messages : 2 925
Points : 4 547
Points : 4 547
tu as tenté un BULK COLLECT ?
__________________
Mon blog : laurentschneider.com
Mon livre : Advanced Oracle SQL Programming
laurentschneider est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/04/2011, 11h10   #5
Nouveau Membre du Club
 
Inscription : juin 2007
Messages : 271
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 271
Points : 32
Points : 32
J'ai essayé :
Code :
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 :
1
2
 
PLS-00497: impossible de mélanger des clauses mono- et multi-lignes (BULK) da
v_ligne es tde type VARCHAR2(255)
...????
ouinih est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/04/2011, 11h11   #6
Membre chevronné
 
Homme O. Joly
Support
Inscription : décembre 2010
Messages : 287
Détails du profil
Informations personnelles :
Nom : Homme O. Joly
Âge : 38
Localisation : France, Seine et Marne (Île de France)

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

Informations forums :
Inscription : décembre 2010
Messages : 287
Points : 617
Points : 617
Il doit manquer quelques infos

J'ai fait le test suivant

Code :
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 :
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 :
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 ...
ojo77 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/04/2011, 11h22   #7
Nouveau Membre du Club
 
Inscription : juin 2007
Messages : 271
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 271
Points : 32
Points : 32
je ne comprends pas...
ouinih est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/04/2011, 11h32   #8
Membre chevronné
 
Homme O. Joly
Support
Inscription : décembre 2010
Messages : 287
Détails du profil
Informations personnelles :
Nom : Homme O. Joly
Âge : 38
Localisation : France, Seine et Marne (Île de France)

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

Informations forums :
Inscription : décembre 2010
Messages : 287
Points : 617
Points : 617
Pouvez vous lancez la fonction avec une trace 10046 afin d'analyser ou le tempos est perdu et poster le tkprof ?
ojo77 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/04/2011, 19h52   #9
McM
Expert Confirmé Sénior
 
Inscription : juillet 2003
Messages : 3 437
Détails du profil
Informations forums :
Inscription : juillet 2003
Messages : 3 437
Points : 4 173
Points : 4 173
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
McM est déconnecté   Envoyer un message privé Réponse avec citation 10
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 05h20.


 
 
 
 
Partenaires

Hébergement Web