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 20/01/2011, 17h37   #1
Membre expérimenté
 
François
Inscription : février 2010
Messages : 305
Détails du profil
Informations personnelles :
Nom : François

Informations forums :
Inscription : février 2010
Messages : 305
Points : 535
Points : 535
Par défaut Hints en PL/SQL

Bonjour,

Afin de mener des tests de performances, je cherche a lancer un select en parallele.

Code :
1
2
WITH test$mt AS (SELECT n FROM cpu_test WHERE rownum <= 4 )
SELECT /*+ PARALLEL (P 4) 40 */ ma_func_de_test FROM test$mt P;
Fonctionne parfaitement dans SQL*Plus. Je le vois avec SQLTrace et le nombre d'IO.

Ceci dit, je voudrais bien l'integrer dans mon package PL/SQL.
Mais bon, EXECUTE IMMEDIATE ne fonctionne pas (Any valid SQL command except SELECT can be run immediately.), et je peux pas l'ecrire directement sous la forme d'un select, les Hints sont pris (a juste titre) pour des commentaires.

Code :
1
2
3
4
5
6
7
8
9
10
 
      WITH TEST$MT AS
       (SELECT N
          FROM CPU_TEST
         WHERE ROWNUM <= NUM_OF_THREAD )
      SELECT /*+ PARALLEL (P  || NUM_OF_THREAD || ') ' ||
                                     G_LONGOP.SOFAR || ' */
       ma_function 
        INTO STR
        FROM TEST$MT P;
L'un d'entre vous aurait-il une idee?
Rams7s est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/01/2011, 17h48   #2
Membre chevronné
 
Avatar de Z3phur
 
Homme loic
Administrateur de base de données
Inscription : décembre 2007
Messages : 673
Détails du profil
Informations personnelles :
Nom : Homme loic
Âge : 37
Localisation : France, Val de Marne (Île de France)

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

Informations forums :
Inscription : décembre 2007
Messages : 673
Points : 773
Points : 773
Bonjour,

as-tu essayé comme ceci :

Code :
1
2
3
4
5
6
7
8
9
10
11
text:='WITH TEST$MT AS
       (SELECT N
          FROM CPU_TEST
         WHERE ROWNUM <= NUM_OF_THREAD )
      SELECT /*+ PARALLEL (P ' || NUM_OF_THREAD || ') ' ||
                                     G_LONGOP.SOFAR || ' */
       ma_function 
        INTO STR
        FROM TEST$MT P';
 
execute immediate text;
__________________
==========================================
La justice sans la force est impuissante, la force sans la justice est tyrannique...
Z3phur est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/01/2011, 09h26   #3
Membre Expert
 
Avatar de Garuda
 
Homme Philippe CHIRCOP
Chef de projet
Inscription : juin 2007
Messages : 1 109
Détails du profil
Informations personnelles :
Nom : Homme Philippe CHIRCOP
Localisation : France

Informations professionnelles :
Activité : Chef de projet
Secteur : Bâtiment

Informations forums :
Inscription : juin 2007
Messages : 1 109
Points : 1 559
Points : 1 559
Ou ca
Code :
1
2
3
execute immediate '
SELECT /*+ PARALLEL (P 4) 40 */ ma_func_de_test FROM (SELECT n FROM cpu_test WHERE rownum <= 4 )';
__________________
Garuda गरूड
Brahmâ la Guerre et Vishnu la Paix

Oracle 10.2.0.4 - Forms6i patch 17 - Toad 11.1 - sharePoint 2010
Garuda est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/01/2011, 11h26   #4
Membre expérimenté
 
François
Inscription : février 2010
Messages : 305
Détails du profil
Informations personnelles :
Nom : François

Informations forums :
Inscription : février 2010
Messages : 305
Points : 535
Points : 535
Bonjour,

Merci de votre aide.

Malheureusement, cela ne fonctionne pas.
Ci-dessous le script de test que j'ai utilise. Peut-etre que j'ai rate une etape.


Afin de bien voir si ca lancait en parallele ou pas, j'ai sorti le dbms_output et l'insertion dans une autre table.
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
 
DROP TABLE tmp;
DROP TABLE tmp2;
--Log table
CREATE TABLE tmp (p1 number);
--Table pour lancer plusieurs fois la function
CREATE TABLE tmp2 (n) AS SELECT rownum FROM all_tables WHERE rownum<500;
 
--Fonction a lancer
CREATE OR REPLACE FUNCTION PARA_TEST RETURN NUMBER IS
  PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  DBMS_OUTPUT.PUT_LINE('a');
  INSERT INTO TMP (P1) VALUES (12);
  COMMIT;
  RETURN 42;
END PARA_TEST;
/
 
CREATE OR REPLACE PROCEDURE MY_PROC1 IS
BEGIN
  EXECUTE IMMEDIATE 'SELECT /*+ PARALLEL (P 4) 40 */ PARA_TEST FROM (SELECT n FROM tmp2 WHERE rownum <= 8 )';
END MY_PROC1;
/
 
CREATE OR REPLACE PROCEDURE MY_PROC2 IS
text varchar2(1000);
BEGIN
text:= 'SELECT /*+ PARALLEL (P 4) 40 */ PARA_TEST FROM (SELECT n FROM tmp2 WHERE rownum <= 8 )';
dbms_output.put_line(text);
execute immediate text;
END MY_PROC2;
/
 
SET serveroutput ON
SELECT /*+ PARALLEL (P 4) 40 */ para_test FROM tmp2 P WHERE rownum<=8;
SELECT * FROM tmp;
 
DELETE FROM tmp;
prompt =============
prompt execute immediate:
exec my_proc1;
SELECT * FROM tmp;
 
DELETE FROM tmp;
prompt =============
prompt avec text:=
exec my_proc2
SELECT * FROM tmp;
 
DELETE FROM tmp;
En faisant un copie/colle a la main du prompt avec text cela fonctionne.

Sinon je vais rester sur DBMS_SCHEDULER, mais je me disais que ce serait plus elegant de faire ca avec un select et un hint.
Rams7s est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/01/2011, 16h12   #5
Membre confirmé
 
Avatar de LBO72
 
Inscription : mai 2007
Messages : 385
Détails du profil
Informations personnelles :
Âge : 43
Localisation : France

Informations forums :
Inscription : mai 2007
Messages : 385
Points : 282
Points : 282
Bonjour,

Je me suis déjà heurté à ce problème. Il m'a fait arracher le peu de cheveux qui me restent :-)

Essayes d'écrite ton hint comme ceci :
--+ TonHint
et non pas comme cela :
/*+ TonHint */.

LBO72.
LBO72 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/01/2011, 20h43   #6
Membre Expert
 
Avatar de pachot
 
Homme Franck Pachot
DBA Oracle
Inscription : novembre 2007
Messages : 703
Détails du profil
Informations personnelles :
Nom : Homme Franck Pachot
Âge : 41
Localisation : Suisse

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

Informations forums :
Inscription : novembre 2007
Messages : 703
Points : 1 630
Points : 1 630
Bonjour,
- execute immediate permet de faire un select into
- pl/sql reconnait les hint et ne les prends pas pour des commentaires
- '40' n'est pas un hint
Cordialement,
Franck.
__________________
A lire sur mon blog Oracle - Articles d'Experts des articles traduits en français de Jonathan Lewis, Tom Kyte, Doug Burns, Cary Millsap, Greg Rahn ...
pachot est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 25/01/2011, 10h30   #7
Membre expérimenté
 
François
Inscription : février 2010
Messages : 305
Détails du profil
Informations personnelles :
Nom : François

Informations forums :
Inscription : février 2010
Messages : 305
Points : 535
Points : 535
Bonjour,

Je pense que c'est le INTO qui résout tout.
Merci Franck.

L’un dans l’autre c’est vrai que faire un select sans la clause INTO, il n’y avait pas de gros intérêt à l’exécuter dans le cas général. Je ne pense pas que j’y aurai pensé de si tôt.

Concernant le 40, il est là pour parser une nouvelle requête à chaque fois. Dans le code il est ajouté dynamiquement par concaténation.

Merci aussi pour les différentes réponses plus ou moins au hasard.

Je note en dessous le bout de script SQL utilisé pour tester les différentes solutions. La solution avec INTO (myproc 4 et 5) fonctionne.
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
 
DROP TABLE tmp;
DROP TABLE tmp2;
--Log table
CREATE TABLE tmp (p1 number);
--Table pour lancer plusieurs fois la function
CREATE TABLE tmp2 (n) AS SELECT rownum FROM all_tables WHERE rownum<500;
 
--Fonction a lancer
CREATE OR REPLACE FUNCTION PARA_TEST RETURN NUMBER IS
  PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  DBMS_OUTPUT.PUT_LINE('a');
  INSERT INTO TMP (P1) VALUES (12);
  COMMIT;
  RETURN 42;
END PARA_TEST;
/
 
CREATE OR REPLACE PROCEDURE MY_PROC1 IS
BEGIN
  EXECUTE IMMEDIATE 'SELECT /*+ PARALLEL (P 4) */ PARA_TEST FROM (SELECT n FROM tmp2 WHERE rownum <= 8 )';
END MY_PROC1;
/
 
CREATE OR REPLACE PROCEDURE MY_PROC2 IS
text varchar2(1000);
BEGIN
text:= 'SELECT /*+ PARALLEL (P 4) */ PARA_TEST FROM (SELECT n FROM tmp2 WHERE rownum <= 8 )';
dbms_output.put_line(text);
execute immediate text;
END MY_PROC2;
/
 
 
CREATE OR REPLACE PROCEDURE MY_PROC3 IS
text varchar2(1000);
BEGIN
text:= 'SELECT --+ PARALLEL (P 4) 
PARA_TEST FROM (SELECT n FROM tmp2 WHERE rownum <= 8 )';
dbms_output.put_line(text);
execute immediate text;
END MY_PROC3;
/
 
 
CREATE OR REPLACE PROCEDURE MY_PROC4 IS
text varchar2(1000);
type t_num IS TABLE of number;
N t_num;
BEGIN
text:= 'SELECT --+ PARALLEL (P 4) 
PARA_TEST FROM (SELECT n FROM tmp2 WHERE rownum <= 8 )';
dbms_output.put_line(text);
execute immediate text BULK COLLECT INTO N;
END MY_PROC4;
/
 
CREATE OR REPLACE PROCEDURE MY_PROC5 IS
text varchar2(1000);
type t_num IS TABLE of number;
N t_num;
BEGIN
text:= 'SELECT /*+ PARALLEL (P 4) 40*/ PARA_TEST FROM (SELECT n FROM tmp2 WHERE rownum <= 8 )';
dbms_output.put_line(text);
execute immediate text BULK COLLECT INTO N;
END MY_PROC5;
/
 
SET serveroutput ON
SELECT /*+ PARALLEL (P 4) 40 */ para_test FROM tmp2 P WHERE rownum<=8;
SELECT * FROM tmp;
 
DELETE FROM tmp;
prompt =============
prompt execute immediate:
exec my_proc1;
SELECT * FROM tmp;
 
DELETE FROM tmp;
prompt =============
prompt avec text:=
exec my_proc2
SELECT * FROM tmp;
 
DELETE FROM tmp;
 
prompt =============
prompt avec text:= et hint --+
exec my_proc3
SELECT * FROM tmp;
 
DELETE FROM tmp;
 
prompt =============
prompt avec text:= et hint --+ avec into
exec my_proc4
SELECT * FROM tmp;
 
DELETE FROM tmp;
 
prompt =============
prompt avec text:= et hint /*+ avec into */
exec my_proc5
SELECT * FROM tmp;
 
DELETE FROM tmp;
Rams7s est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/03/2011, 15h56   #8
Invité de passage
 
Homme
Consultant informatique
Inscription : mars 2011
Messages : 1
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Belgique

Informations professionnelles :
Activité : Consultant informatique

Informations forums :
Inscription : mars 2011
Messages : 1
Points : 1
Points : 1
Par défaut petit détail ?

Bonjour, sans vouloir trop m'avancer, je constate que dans l'execute immediate, il n'y a pas d'alias P (à l'inverse du second test), donc le P du hint ne veut rien dire pour Oracle.
D'où peut-être les problèmes?

Bien cordialement,
vlapoulle
vlapoulle est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 00h17.


 
 
 
 
Partenaires

Hébergement Web