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 :

temps d'exéc très différent sur DELETE entre SQL et PL/SQL


Sujet :

PL/SQL Oracle

  1. #1
    Membre régulier
    Inscrit en
    Janvier 2006
    Messages
    120
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 120
    Points : 88
    Points
    88
    Par défaut temps d'exéc très différent sur DELETE entre SQL et PL/SQL
    Bonjour,

    Je tente de faire un DELETE massif de 82000 rows d'une table, sur un champ qui est INDEXE.

    J'ai effectué plusieurs fois le même test, sur la même table, avec les mêmes données, pour être certain que la différence ne venait pas d'une charge différente de la machine à plusieurs moments, mais le résultat est toujours le même :

    1) Via FORMS :

    13:28:33 - del_imgext(253,OUI) BEGIN
    13:29:23 - 82000 valeur image deleted
    13:29:24 - 1 image deleted
    13:29:24 - del_imgext(253,OUI) END

    Donc environ 50 secondes...

    2) Via PL/SQL sous Toad :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    BEGIN
      DBMS_OUTPUT.put_line (TO_CHAR (SYSDATE, 'hh24:mi:ss'));
      mgckgimgext.del_imgext (253, 'OUI');
      DBMS_OUTPUT.put_line (TO_CHAR (SYSDATE, 'hh24:mi:ss'));
    END;
    14:03:08
    14:03:48


    Soit environ 40 secondes...

    3) DELETE Direct en PL/SQL sous Toad :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    BEGIN
      DBMS_OUTPUT.put_line (TO_CHAR (SYSDATE, 'hh24:mi:ss'));
      DELETE FROM valeur_image
            WHERE idtimgext = 253;
      DBMS_OUTPUT.put_line (TO_CHAR (SYSDATE, 'hh24:mi:ss'));
    END;
    14:05:08
    14:05:49

    Soit environ 40 secondes...

    4) DELETE Direct en SQL sous Toad :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    DELETE FROM valeur_image
            WHERE idtimgext = 253;
    Environ 18 secondes...


    Donc 1 (50") > 2 (40") = 3 (40") > 4 (18")

    On passe presque du simple au triple entre 1 et 4 ...

    Si quelqu'un a une idée.... Moi je perds mon latin...

    Merci!

  2. #2
    Membre expert
    Avatar de LeoAnderson
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 2 938
    Points : 3 199
    Points
    3 199
    Par défaut
    Sans avoir le code de la fameuse procédure, il va être difficile d'expliquer précisément le pourquoi de la différence (qui sait, il y a peut être une attente volontaire de 50 secondes) ! :-)

    Mais de manière générale, ce qui peut être fait en SQL doit être fait en SQL et on ne doit réserver le PL/SQL que pour des traitements particuliers...

  3. #3
    Membre régulier
    Inscrit en
    Janvier 2006
    Messages
    120
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 120
    Points : 88
    Points
    88
    Par défaut
    Leo,

    Merci pour ta réponse.

    Voici le code de la "fameuse procédure".

    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
     
    CREATE OR REPLACE PROCEDURE DEL_IMGEXT
     (P_IDTIMGEXT IN image_extraction.idtimgext%TYPE
     ,P_TYPE IN VARCHAR2 := 'OUI'
     )
     IS
    BEGIN
      qms$errors.show_debug_info('del_imgext('||p_idtimgext||','||p_type||') BEGIN');
     
      DELETE     
        FROM valeur_image
       WHERE idtimgext = p_idtimgext;
      qms$errors.show_debug_info(SQL%ROWCOUNT||' valeur image deleted');  
     
      IF p_type = 'OUI'
      THEN
        DELETE
          FROM image_extraction
         WHERE idtimgext = p_idtimgext;
        qms$errors.show_debug_info(SQL%ROWCOUNT||' image deleted');  
      END IF;
     
      qms$errors.show_debug_info('del_imgext('||p_idtimgext||','||p_type||') END');
    END del_imgext;
    Mais même sans passer par cette procédure, le DELETE en PL/SQL est aussi lent (voir comparaisons entre point 2) et point 3) : 40 secondes tous les deux, alors que ça ne met que 18 secondes en SQL...).

    Merci encore.

    Nicolas.

  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
    Citation Envoyé par Nico57
    3) DELETE Direct en PL/SQL sous Toad :

    Code:

    BEGIN
    DBMS_OUTPUT.put_line (TO_CHAR (SYSDATE, 'hh24:mi:ss'));
    DELETE FROM valeur_image
    WHERE idtimgext = 253;
    DBMS_OUTPUT.put_line (TO_CHAR (SYSDATE, 'hh24:mi:ss'));
    END;


    14:05:08
    14:05:49

    Soit environ 40 secondes...

    4) DELETE Direct en SQL sous Toad :

    Code:

    DELETE FROM valeur_image
    WHERE idtimgext = 253;

    Environ 18 secondes...
    c'est étrange. mais comment as-tu testé?

    le mieux serait un tkprof dans sqlplus, en vidant le cache avant, et rollback après, afin de voir ou le temps est perdu. Il est étonnant de croire que les 2 outputs ton coûté plus de 20 secondes

  5. #5
    Membre régulier
    Inscrit en
    Janvier 2006
    Messages
    120
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 120
    Points : 88
    Points
    88
    Par défaut
    Bonjour Laurent,

    Les deux outputs ne me servaient qu'à indiquer correctement le temps, mais même en les commentant, et en chronométrant manuellement, je tourne toujours autour de 40 secondes

  6. #6
    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
    oui, mais si tu effaces 2 fois la même ligne, la deuxieme c'est plus rapide (car il n'y a plus rien a effacé) ;-)

    il s'agit de déterminer si la différence est vraiment due à PL/SQL.

    il est normal que ça aille un peu plus vite en SQL, car il est préférable d'appeler DELETE directement.

    si la différence n'est pas visible dans sqlplus, mais seulement dans TOad, alors c'est pas de chance

  7. #7
    Membre régulier
    Inscrit en
    Janvier 2006
    Messages
    120
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 120
    Points : 88
    Points
    88
    Par défaut
    Je précise que j'effaçais bien à chaque fois 82000 lignes, car je faisais un ROLLBACK entre chaque instruction.

    J'ai de plus lancé plusieurs fois le test, parfois d'abord en SQL, parfois d'abord en PL/SQL pour être certain qu'il ne s'agisse pas de problèmes de cache ou autres.

    Voici le résultat sous SQL+ :

    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
     
    SQL> DELETE FROM valeur_image
      2        WHERE idtimgext = 253;
     
    82000 rows deleted.
     
    Elapsed: 00:00:18.05
    SQL> rollback;
     
    Rollback complete.
     
    Elapsed: 00:00:07.01
    SQL> BEGIN
      2    DBMS_OUTPUT.put_line (TO_CHAR (SYSDATE, 'hh24:mi:ss'));
      3    DELETE FROM valeur_image WHERE idtimgext = 253;
      4    DBMS_OUTPUT.put_line (TO_CHAR (SYSDATE, 'hh24:mi:ss'));
      5  END;
      6  /
     
    PL/SQL procedure successfully completed.
     
    Elapsed: 00:00:42.07

  8. #8
    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
    essaye de voir si tu trouves quelque indice avec tkprof

    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
    SQL> alter session set sql_trace=true;
     
    Session altered.
     
    SQL> exec DELETE FROM valeur_image WHERE idtimgext = 253;
     
    PL/SQL procedure successfully completed.
     
    SQL> quit
    ...
     
    SQL> alter session set sql_trace=true;
     
    Session altered.
     
    SQL> DELETE FROM valeur_image WHERE idtimgext = 253;
    ensuite, dans ton user_dump_dest, tu fais

    tkprof file1.trc PLSQL.tp SYS=NO
    tkprof file2.trc purSQL.tp SYS=NO

    et tu compares les fichiers générés pour voir où est la différence

  9. #9
    Membre expert
    Avatar de LeoAnderson
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 2 938
    Points : 3 199
    Points
    3 199
    Par défaut
    Le test de comparaison avec d'abord le delete en SQL et ensuite en PL/SQL me semble assez probant.

    La proposition de Laurent est évidemment la bonne (tracer + tkprof) mais je préferais avoir les infos de wait d'où l'idée d'utiliser l'event 10046.
    cf http://leoanderson.developpez.com/tr...-oracle/#LII-B

    PS : le fait de faire ROLLBAK préserve les lignes mais ne réinitialise pas le cache ;-)

  10. #10
    Membre régulier
    Inscrit en
    Janvier 2006
    Messages
    120
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 120
    Points : 88
    Points
    88
    Par défaut
    Leo et Laurent, merci pour vos suggestions, mais n'ayant pas accès à la machine hébergeant le serveur Oracle, je vais devoir me battre avec les DBAs pour qu'ils daignent lance la commande tkprof et m'envoyer le résultat.... Je tenterai de le faire cet après-midi, car ce matin la machine est trop chargée (l'export tourne encore).

    En tout cas, pour vous montrer que le problème ne vient pas du cache, j'ai lancé plusieurs fois à la suite le DELETE en SQL et en PL/SQL. Les temps de réponse sont constants (s'il s'agissait d'un problème de cache, je pense que ma première commande serait lente, puis les autres rapides) : les deux SQL prennent le même temps à peu près, et moins de temps que les deux PL/SQL, qui eux aussi prennent à peu près le même temps.

    Comme je l'ai dit, les temps sont en tout les cas + lents qu'hier, car l'export de la base tourne encore :

    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
    35
    36
    37
    38
    39
    40
    41
    42
     
    SQL> set timing on
    SQL> exec DELETE FROM valeur_image WHERE idtimgext = 257;
     
    PL/SQL procedure successfully completed.
     
    Elapsed: 00:01:46.07
    SQL> rollback;
     
    Rollback complete.
     
    Elapsed: 00:01:11.06
    SQL> DELETE FROM valeur_image WHERE idtimgext = 257;
     
    82000 rows deleted.
     
    Elapsed: 00:00:48.02
    SQL> rollback;
     
    Rollback complete.
     
    Elapsed: 00:00:21.07
    SQL> exec DELETE FROM valeur_image WHERE idtimgext = 257;
     
    PL/SQL procedure successfully completed.
     
    Elapsed: 00:01:55.09
    SQL> rollback;
     
    Rollback complete.
     
    Elapsed: 00:01:06.05
    SQL> DELETE FROM valeur_image WHERE idtimgext = 257;
     
    82000 rows deleted.
     
    Elapsed: 00:00:43.06
    SQL> rollback;
     
    Rollback complete.
     
    Elapsed: 00:00:14.03
    Donc :
    DELETE PL/SQL : environ 1 minute 50s.
    ROLLBACK après DELETE PL/SQL : environ 1 minute 10s.
    DELETE SQL : environ 50s.
    ROLLBACK après DELETE SQL : environ 20s.

    D'ailleurs, si quelqu'un peut m'expliquer pourquoi le temps d'exécution des ROLLBACKS sont différents, selon que le DELETE a été fait en PL/SQL ou SQL, ça éclaircirait ma lanterne...

    Merci encore,

    Nico'

  11. #11
    Membre régulier
    Inscrit en
    Janvier 2006
    Messages
    120
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 120
    Points : 88
    Points
    88
    Par défaut
    Resalut,

    J'ai lancé les requêtes, d'abord le SQL puis le PL/SQL en Event 10046.

    Voici les résultats partiels :

    SQL :
    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
    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
     
    ********************************************************************************
     
    DELETE FROM valeur_image 
    WHERE
     idtimgext = 257
     
     
    call     count       cpu    elapsed       disk      query    current        rows
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    Parse        1      0.01       0.00          0          0          0           0
    Execute      1     13.29      38.87       2014        326      92955       82000
    Fetch        0      0.00       0.00          0          0          0           0
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    total        2     13.30      38.88       2014        326      92955       82000
     
    Misses in library cache during parse: 1
    Optimizer goal: RULE
    Parsing user id: 1608  (MGC)
     
    Rows     Row Source Operation
    -------  ---------------------------------------------------
          0  DELETE  
      82000   INDEX RANGE SCAN VALIMG_IMGEXT_FK_I (object id 2497851)
     
     
    Rows     Execution Plan
    -------  ---------------------------------------------------
          0  DELETE STATEMENT   GOAL: RULE
          0   DELETE OF 'VALEUR_IMAGE'
      82000    INDEX   GOAL: ANALYZED (RANGE SCAN) OF 'VALIMG_IMGEXT_FK_I' 
                   (NON-UNIQUE)
     
     
    Elapsed times include waiting on following events:
      Event waited on                             Times   Max. Wait  Total Waited
      ----------------------------------------   Waited  ----------  ------------
      log buffer space                               17        0.18          1.25
      direct path write                               8        0.03          0.05
      direct path read                               22        0.02          0.13
      db file sequential read                       189        0.14          1.01
      SQL*Net message to client                       1        0.00          0.00
      SQL*Net message from client                     1       26.76         26.76
    ********************************************************************************
    ********************************************************************************
     
    rollback
     
     
    call     count       cpu    elapsed       disk      query    current        rows
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    Parse        1      0.00       0.00          0          0          0           0
    Execute      1      4.73      18.24          0        852     173464           0
    Fetch        0      0.00       0.00          0          0          0           0
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    total        2      4.73      18.24          0        852     173464           0
     
    Misses in library cache during parse: 1
    Optimizer goal: RULE
    Parsing user id: 1608  (MGC)
     
    Elapsed times include waiting on following events:
      Event waited on                             Times   Max. Wait  Total Waited
      ----------------------------------------   Waited  ----------  ------------
      log buffer space                               28        1.00          5.77
      log file sync                                   1        0.05          0.05
      SQL*Net message to client                       2        0.00          0.00
      SQL*Net message from client                     2       26.06         32.89
      SQL*Net break/reset to client                   2        0.00          0.00
    ********************************************************************************
    PLSQL :
    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
    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
     
    ********************************************************************************
     
    BEGIN DELETE FROM valeur_image WHERE idtimgext = 257; END;
     
     
    call     count       cpu    elapsed       disk      query    current        rows
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    Parse        1      0.01       0.00          0          0          0           0
    Execute      1     31.00     120.56          4        466     913562           1
    Fetch        0      0.00       0.00          0          0          0           0
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    total        2     31.01     120.57          4        466     913562           1
     
    Misses in library cache during parse: 1
    Optimizer goal: RULE
    Parsing user id: 1608  (MGC)
     
    Elapsed times include waiting on following events:
      Event waited on                             Times   Max. Wait  Total Waited
      ----------------------------------------   Waited  ----------  ------------
      SQL*Net message to client                       1        0.00          0.00
      SQL*Net message from client                     1        8.45          8.45
    ********************************************************************************
     
    DELETE FROM VALEUR_IMAGE 
    WHERE
     IDTIMGEXT = 257
     
     
    call     count       cpu    elapsed       disk      query    current        rows
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    Parse        1      0.00       0.00          0          0          0           0
    Execute      1     31.00     120.56          4        466     913562       82000
    Fetch        0      0.00       0.00          0          0          0           0
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    total        2     31.00     120.56          4        466     913562       82000
     
    Misses in library cache during parse: 1
    Optimizer goal: RULE
    Parsing user id: 1608  (MGC)   (recursive depth: 1)
     
    Rows     Row Source Operation
    -------  ---------------------------------------------------
          0  DELETE  
      82000   INDEX RANGE SCAN VALIMG_IMGEXT_FK_I (object id 2497851)
     
     
    Rows     Execution Plan
    -------  ---------------------------------------------------
          0  DELETE STATEMENT   GOAL: RULE
          0   DELETE OF 'VALEUR_IMAGE'
      82000    INDEX   GOAL: ANALYZED (RANGE SCAN) OF 'VALIMG_IMGEXT_FK_I' 
                   (NON-UNIQUE)
     
     
    Elapsed times include waiting on following events:
      Event waited on                             Times   Max. Wait  Total Waited
      ----------------------------------------   Waited  ----------  ------------
      log buffer space                               73        0.46          6.68
      buffer busy waits                               1        0.05          0.05
      resmgr:waiting in check2                      412        0.26         15.52
      log file switch completion                      2        0.25          0.45
      resmgr:waiting in check                         8        0.07          0.13
      latch free                                      1        0.00          0.00
      db file sequential read                         2        0.07          0.08
    ********************************************************************************
    ********************************************************************************
     
    rollback
     
     
    call     count       cpu    elapsed       disk      query    current        rows
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    Parse        1      0.00       0.00          0          0          0           0
    Execute      1     19.51      63.64       2124       4110     827976           0
    Fetch        0      0.00       0.00          0          0          0           0
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    total        2     19.51      63.64       2124       4110     827976           0
     
    Misses in library cache during parse: 0
    Optimizer goal: RULE
    Parsing user id: 1608  (MGC)
     
    Elapsed times include waiting on following events:
      Event waited on                             Times   Max. Wait  Total Waited
      ----------------------------------------   Waited  ----------  ------------
      log buffer space                               20        0.93          3.37
      resmgr:waiting in end wait                      1        0.04          0.04
      db file sequential read                      2124        0.44         16.48
      log file switch completion                      2        0.25          0.44
      log file sync                                   1        0.01          0.01
      SQL*Net message to client                       1        0.00          0.00
      SQL*Net message from client                     1       17.08         17.08
    ********************************************************************************
    Il y a donc des différences flagrantes :
    1) Entre SQL et PL/SQL, lors du DELETE, le chiffre indiqué pour la colonne current de Execute est multiplié par 10 !!! (le temps écoulé est multiplié par 3)

    2) Entre SQL et PL/SQL, lors du ROLLBACK, le chiffre indiqué pour la colonne current de Execute est multiplié par 4 !!! (le temps écoulé est multiplié par 3). De plus il y a du "Disk" en PL/SQL alors qu'il n'y en a pas en SQL.

    Mais j'avoue que je ne sais pas trop comment interpréter ces résultats...

    Merci pour votre aide.

    Nicolas.

    P.S. : Leo, dans ton document http://leoanderson.developpez.com/tr...ssions-oracle/ , il y a une petite faute de frappe dans le chapitre II-B. Event 10046 :
    Il faudrait remplacer "ALTER SESSION SET EVENT '10046 trace name context off';" par "ALTER SESSION SET EVENTS '10046 trace name context off';" (EVENTS à la place de EVENT, et la coloration syntaxique bleue au lieu de noir).

  12. #12
    Membre expert

    Profil pro
    Inscrit en
    Février 2006
    Messages
    3 437
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 3 437
    Points : 3 597
    Points
    3 597
    Par défaut
    Est-ce qu'on pourrait avoir:
    - la version d'Oracle
    - config rollback segments ou undo
    - la structure de la table
    - la taille de la table (nombre d'extents)

  13. #13
    Membre expert
    Avatar de LeoAnderson
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 2 938
    Points : 3 199
    Points
    3 199
    Par défaut
    Je constate que dans le cas PL/SQL il y a des waits liés au ressource manager alors qu'il n'y en a pas du tout en SQL.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    resmgr:waiting in check2                      412        0.26         15.52
    Est-ce que les tests sont bien réalisés avec le même compte ?

    Est-ce que les groupes de consommateurs de ressources sont utilisés ? comment ?

    D'accord, les temps d'attente annoncés ne compensent pas à eux seuls les écarts, mais tout de même...

  14. #14
    Membre régulier
    Inscrit en
    Janvier 2006
    Messages
    120
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 120
    Points : 88
    Points
    88
    Par défaut
    @Pifor =>

    - la version d'Oracle : Oracle 9i
    - config rollback segments ou undo : je ne sais pas comment obtenir cette info
    - la structure de la table :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    CREATE TABLE VALEUR_IMAGE
    (
      IDTVALIMG  NUMBER(12)                         NOT NULL,
      IDTAFLPLN  NUMBER(12)                         NOT NULL,
      IDTELM     NUMBER(12)                         NOT NULL,
      IDTIMGEXT  NUMBER(12)                         NOT NULL,
      TYPIMG     VARCHAR2(3 BYTE)                   DEFAULT 'AVN'                 NOT NULL,
      DTECRE     DATE                               NOT NULL,
      UTLCRE     VARCHAR2(30 BYTE)                  NOT NULL,
      VALIMG     VARCHAR2(240 BYTE),
      DTEMAJ     DATE,
      UTLMAJ     VARCHAR2(30 BYTE)
    )
    - la taille de la table (nombre d'extents) : 5 Mo (20 extents)

    @LeoAnderson =>

    Oui, les tests sont réalisés avec le même compte, sur la même base, le même schéma etc... Quant aux groupes de consommateurs de ressources, j'avoue ne pas savoir ce que c'est...

    Merci pour votre aide.

  15. #15
    Membre averti

    Inscrit en
    Septembre 2003
    Messages
    425
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 425
    Points : 398
    Points
    398
    Par défaut
    Excusez moi, mais cela a peut être rien à voir mais nous avons eu des temps de réponse déplorable avec PL/SQL et correcte avec SQL.
    cf post http://www.developpez.net/forums/vie...960&highlight=

    Assure toi que le typage du champ conditionné soit le même que celui de la valeur intérrogée.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    DECLARE
    widtimgext         valeur_image.idtimgext%type := 253;
    BEGIN 
      DBMS_OUTPUT.put_line (TO_CHAR (SYSDATE, 'hh24:mi:ss')); 
      DELETE FROM valeur_image 
            WHERE idtimgext = widtimgext; 
      DBMS_OUTPUT.put_line (TO_CHAR (SYSDATE, 'hh24:mi:ss')); 
    END;
    Je sais que pour un insert, oracle convertit les values(,,) avec le même type que les champs dans lesquels tu vas les insérér.
    Et que lors d'une condition ORACLE, convertit tout ton champs au même type que la variable de ta condition.

    Dans notre cas, nous intérrogions des champs de type VARCHAR2(3) avec des constantes en char(3), je peux te dire que la différence de temps de réponse est ENORME.

    Dans ton exemple vu que tu es en 9i, les nombre doivent être interprété en pls_integer et non en number(12) comme le décrit ta table.


    Fait un test et tiens nous au courant

  16. #16
    Membre régulier
    Inscrit en
    Janvier 2006
    Messages
    120
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 120
    Points : 88
    Points
    88
    Par défaut
    Bonjour Sygale,

    Merci pour ta suggestion.

    J'ai fait le test, mais, malheureusement, ça n'a rien changé...

    Je pense que bien que je DELETE 82000 Rows, je le fais en UN SEUL DELETE, et non pas en 82000, donc je pense que la conversion de PLS_INTEGER vers NUMBER(12) ne se fait qu'une seule fois, ce qui est négligeable...

    D'autres idées? Je suis preneur.

    Merci.

  17. #17
    Membre expert

    Profil pro
    Inscrit en
    Février 2006
    Messages
    3 437
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 3 437
    Points : 3 597
    Points
    3 597
    Par défaut
    Est-ce que si vous faites plusieurs exécutions consécutives:
    DELETE SQL + ROLLBACK
    puis plusieurs exécutions consécutives:
    DELETE PL/SQL + ROLLBACK

    les temps sont-ils les mêmes avec les mêmes écarts ?

    Pouvez-vous aussi nous donner le nombre de lignes total de la table
    ainsi que le DDL de création de tous les index sur la table en question ?
    Est-ce que vous utilisez une option particulière de la base de données
    qui pourrait en particulier concerner cette table et ces index ?

  18. #18
    Membre régulier
    Inscrit en
    Janvier 2006
    Messages
    120
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 120
    Points : 88
    Points
    88
    Par défaut
    Pifor,

    Si je fais plusieurs DELETE SQL + ROLLBACK PUIS plusieurs DELETE PL/SQL + ROLLBACK, les temps sont sensiblement les mêmes avec les mêmes écarts.

    La table contient en tout 82331 rows.

    Voici le script de création des index :
    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
     
    PROMPT Creating Index 'VALIMG_ELM_FK_I'
    CREATE INDEX VALIMG_ELM_FK_I ON VALEUR_IMAGE
     (IDTELM)
    /
     
    PROMPT Creating Index 'VALIMG_IMGEXT_FK_I'
    CREATE INDEX VALIMG_IMGEXT_FK_I ON VALEUR_IMAGE
     (IDTIMGEXT)
    /
     
    PROMPT Creating Index 'VALIMG_AFLPLN_FK_I'
    CREATE INDEX VALIMG_AFLPLN_FK_I ON VALEUR_IMAGE
     (IDTAFLPLN)
    /
    Aucune option particulière de la base de données ne concerne cette table ni ces index.

    Merci!

  19. #19
    Membre expert

    Profil pro
    Inscrit en
    Février 2006
    Messages
    3 437
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 3 437
    Points : 3 597
    Points
    3 597
    Par défaut
    Peut-être une piste : Cela signfie que le DELETE supprime presque toutes les lignes de la table et qu'il implique des changements importants dans les index mais que le rollback doit de toute façon annuler dans les 2 cas...

    Je n'arrive toujours pas à comprendre pourquoi l'exécution par PL/SQL prend beaucoup plus de temps: la valeur "current" dans l'analyse de tkprof représente des accès cache qui peuvent provenir d'importantes modifications effectuées par la requête ou d'accès important au dictionnaire.

    Si vous avez un contrat de support Oracle, je vous conseillerais d'ouvrir un incident chez eux avec tous les éléments que vous avez donnés ici.

  20. #20
    Membre averti

    Inscrit en
    Septembre 2003
    Messages
    425
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 425
    Points : 398
    Points
    398
    Par défaut
    Citation Envoyé par Nico57
    Je pense que bien que je DELETE 82000 Rows, je le fais en UN SEUL DELETE, et non pas en 82000, donc je pense que la conversion de PLS_INTEGER vers NUMBER(12) ne se fait qu'une seule fois, ce qui est négligeable...
    Et non oracle convertit toute la table en pls_integer avant de faire la restriction et de faire le delete !

    Ta question est une très bonne colle, mais je vois rien de plus de mon côté désolé

Discussions similaires

  1. Réponses: 2
    Dernier message: 30/01/2015, 17h20
  2. Réponses: 5
    Dernier message: 25/07/2012, 22h20
  3. Comportement différent sur un DIV entre IE et FF
    Par zooffy dans le forum Balisage (X)HTML et validation W3C
    Réponses: 6
    Dernier message: 07/04/2011, 13h50
  4. Performances trés différentes entre 9i et 10g
    Par ManuDuc dans le forum Administration
    Réponses: 17
    Dernier message: 05/12/2008, 10h24
  5. DELETE très long sur grosse table partitionée
    Par glutock dans le forum SQL
    Réponses: 3
    Dernier message: 28/04/2008, 10h47

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