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

Oracle Discussion :

trigger et performance.


Sujet :

Oracle

  1. #1
    Membre confirmé

    Profil pro
    Inscrit en
    Juin 2004
    Messages
    487
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 487
    Points : 455
    Points
    455
    Par défaut trigger et performance.
    Bonjour à tous,

    je me pose quelques questions sur les triggers au niveau des performances.
    Je parle de tables dans lesquelles ont fait des insert à très grande gréquence.

    Dans ce type de tables, j'ai évidement une séquence comme identifiant unique.

    Ma question:
    -Poser un trigger qui se charge de gerer la séquence est-il plus couteux en terme de performance que de rajouter dans la requete insert la colonne avec sa sequence correspondante?

    (Je pense que oui, mais je peux difficilement mettre en oeuvre la deuxième solution, n'étant pas maitre des codes d'insertion. C'est pour cela que je veux le verifier).

    Et une deuxième subsidiaire.

    Est-ce qu'un trigger sur un update ou un delete peux ralentir un insert (même d'un milliardième de seconde!)?

  2. #2
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    une surcharge de code est toujours pénalisante donc oui un trigger pour la séquence ralenti l'insert mais c'est négligeable et surtout plus pratique

    Pour la deuxiéme question, ça me surprendrait mais Oracle recèle encore quelques secrets bien gardé

  3. #3
    Rédacteur

    Inscrit en
    Septembre 2004
    Messages
    626
    Détails du profil
    Informations forums :
    Inscription : Septembre 2004
    Messages : 626
    Points : 848
    Points
    848
    Par défaut Re: trigger et performance.
    Citation Envoyé par aline
    Est-ce qu'un trigger sur un update ou un delete peux ralentir un insert (même d'un milliardième de seconde!)?
    J'aurais dis non, évidemment Mais les résultats m'ont complètement surpris ! Voici un petit test :

    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
     
    drop table SANS_TRIGGER;
    drop table AVEC_TRIGGER;
     
    create table SANS_TRIGGER as select * from all_objects where 1=0;
     
    create table AVEC_TRIGGER as select * from all_objects where 1=0;
     
    create or replace trigger tu_avec_trigger before update on AVEC_TRIGGER
    begin
       null;
    end;
    /
     
    alter session set sql_trace=true;
    alter session set timed_statistics=true;
     
    insert into SANS_TRIGGER
    select   *
    from     ALL_OBJECTS;
     
    commit;
     
    insert into AVEC_TRIGGER
    select   *
    from     ALL_OBJECTS;
     
    commit;
     
     
    alter session set sql_trace=false;
    alter session set timed_statistics=false;
    Et le résultat 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
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    insert into SANS_TRIGGER
    select   *
    from     ALL_OBJECTS
     
    call     count       cpu    elapsed       disk      query    current        rows
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    Parse        1      0.08       0.09          0          0          0           0
    Execute      1      1.58       1.61        688      16098        482        3337
    Fetch        0      0.00       0.00          0          0          0           0
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    total        2      1.66       1.70        688      16098        482        3337
     
     
    insert into AVEC_TRIGGER
    select   *
    from     ALL_OBJECTS
     
    call     count       cpu    elapsed       disk      query    current        rows
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    Parse        1      0.09       0.08          0          0          0           0
    Execute      1      1.50       1.56        682      16091        481        3337
    Fetch        0      0.00       0.00          0          0          0           0
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    total        2      1.59       1.64        682      16091        481        3337
    Le temps total est inférieur pour l'insertion dans la table AVEC trigger. Il y a même légèrement moins de bloc lu dans le second cas.

    Moralité : mettez partout des triggers qui servent à rien ! (A prendre avec humour bien sûr).

    Quelle est l'erreur ?
    Au niveau du temps je pense que c'est parce que la seconde requête a profité du cache (lecture sur disque 682 blocs contre 688) mais elle fait quand même moins de logical I/O : 16572 contre 16580...

    Quelqu'un a des résultats similaires ? Si oui, comment l'interprétez vous ?



    Laly.

  4. #4
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    C'est pas bon de faire un INSERT AS SELECT, parce que tu ne sais pas si tu testes l'insert ou le select

    Pour faire un test cohérent il faut insérer des valeurs... je te laisse le soin de faire un milliard d'ordre insert pour le test

  5. #5
    Rédacteur

    Inscrit en
    Septembre 2004
    Messages
    626
    Détails du profil
    Informations forums :
    Inscription : Septembre 2004
    Messages : 626
    Points : 848
    Points
    848
    Par défaut
    Oui, bien sûr ! Bien vu Orafrance 8) je refais le test !


    Laly.

  6. #6
    Rédacteur

    Inscrit en
    Septembre 2004
    Messages
    626
    Détails du profil
    Informations forums :
    Inscription : Septembre 2004
    Messages : 626
    Points : 848
    Points
    848
    Par défaut
    Nouveau test :

    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
     
    begin
       for i in 1..10000
       loop
          insert into AVEC_TRIGGER
          values (1);
       end loop;
    end;
    /
     
     
    begin
       for i in 1..10000
       loop
          insert into SANS_TRIGGER
          values (1);
       end loop;
    end;
    /
    Voici le nouveau résultat :


    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
     
    INSERT INTO SANS_TRIGGER 
    VALUES
     ( 1  )
     
     
    call     count       cpu    elapsed       disk      query    current        rows
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    Parse        1      0.01       0.00          0          0          0           0
    Execute  10000      2.77       2.79          2         31      10479       10000
    Fetch        0      0.00       0.00          0          0          0           0
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    total    10001      2.78       2.79          2         31      10479       10000
     
     
     
    INSERT INTO AVEC_TRIGGER 
    VALUES
     ( 1  )
     
     
    call     count       cpu    elapsed       disk      query    current        rows
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    Parse        1      0.01       0.01          0          0          0           0
    Execute  10000      3.03       2.89          5         31      10481       10000
    Fetch        0      0.00       0.00          0          0          0           0
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    total    10001      3.04       2.90          5         31      10481       10000


    La morale est sauve mais on note quand même un ralentissement dans l'insert sur la table avec trigger (1 dixième de secondes en plus)!


    Laly.

  7. #7
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    In Oracle we trust

  8. #8
    Membre confirmé

    Profil pro
    Inscrit en
    Juin 2004
    Messages
    487
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 487
    Points : 455
    Points
    455
    Par défaut
    donc, 1/100000eme de seconde avec le trigger.
    C'est plus que raisonnable!

  9. #9
    Membre confirmé

    Profil pro
    Inscrit en
    Juin 2004
    Messages
    487
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 487
    Points : 455
    Points
    455
    Par défaut
    Je viens de faire un test pas très surprenant

    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
     
    create table avec_trigger( seq1 number, a varchar2(1));
    alter table AVEC_TRIGGER  add constraint seq_pk primary key (SEQ1)
     
     
    create table sans_trigger( seq2 number, a varchar2(1));
    alter table sans_TRIGGER  add constraint seq2_pk primary key (SEQ2)
     
    create sequence seq1 start with 1 increment by 1;
     
    create sequence seq2 start with 1 increment by 1;
     
     
     
    alter session set sql_trace=true;
    alter session set timed_statistics=true;
     
     
    create or replace trigger seq_avec_trigger
    before insert on avec_trigger
    for each row
    begin
        select seq1.nextval into :new.seq1 from dual;
    end;
    /
     
     
     
    begin
       for i in 1..10000
       loop
          insert into AVEC_TRIGGER (a)
          values ('X');
       end loop;
    end;
    /
     
     
    begin
       for i in 1..10000
       loop
          insert into SANS_TRIGGER
          values (i,'X');
       end loop;
    end;
    / 
     
     
    alter session set sql_trace=false;
    alter session set timed_statistics=true;
     
    INSERT into SANS_TRIGGER
          values (:b1,'X')
     
    call     count       cpu    elapsed       disk      query    current        rows
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    Parse        1      0.00       0.00          0          0          0           0
    Execute  10000      0.78       1.13          0         74      30960       10000
    Fetch        0      0.00       0.00          0          0          0           0
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    total    10001      0.78       1.14          0         74      30960       10000
     
     
    INSERT into AVEC_TRIGGER (a)
          values ('X')
     
    call     count       cpu    elapsed       disk      query    current        rows
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    Parse        1      0.00       0.00          0          0          0           0
    Execute  10000      1.76       1.86          0         90      10398       10000
    Fetch        0      0.00       0.00          0          0          0           0
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    total    10001      1.76       1.86          0         90      10398       10000

    Donc, il semblerait qu'il vaut mieux inserer une sequence sans trigger!

  10. #10
    Rédacteur

    Inscrit en
    Septembre 2004
    Messages
    626
    Détails du profil
    Informations forums :
    Inscription : Septembre 2004
    Messages : 626
    Points : 848
    Points
    848
    Par défaut
    Aline,


    J'ai continué à partir de ton test en faisant la même chose mais avec un CACHE de 50 pour la séquence, voici les résultats :

    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
     
    SELECT SEQ_CACHE.NEXTVAL   
    FROM
     DUAL
     
     
    call     count       cpu    elapsed       disk      query    current        rows
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    Parse        1      0.00       0.01          0          0          0           0
    Execute  10000      1.34       1.20          0          0          0           0
    Fetch    10000      4.82       5.12          4      10000      40200       10000
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    total    20001      6.16       6.33          4      10000      40200       10000
     
     
    SELECT SEQ_NOCACHE.NEXTVAL   
    FROM
     DUAL
     
     
    call     count       cpu    elapsed       disk      query    current        rows
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    Parse        1      0.01       0.01          0          0          0           0
    Execute  10000      1.71       1.59          0          0          0           0
    Fetch    10000     29.28      29.75          3      10000      50000       10000
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    total    20001     31.00      31.35          3      10000      50000       10000


    Diminution du temps d'un facteur 5 avec le cas : impressionant !


    Laly.

  11. #11
    Membre confirmé

    Profil pro
    Inscrit en
    Juin 2004
    Messages
    487
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 487
    Points : 455
    Points
    455
    Par défaut
    C'est bien ca!
    Mais c'est combien le cache par défaut dans une séquence?
    20 je crois?!

  12. #12
    Rédacteur

    Inscrit en
    Septembre 2004
    Messages
    626
    Détails du profil
    Informations forums :
    Inscription : Septembre 2004
    Messages : 626
    Points : 848
    Points
    848
    Par défaut
    Oui tu as raison, la valeur par défaut c'est CACHE 20 (en tout en 8.1.7.4).


    Laly.

  13. #13
    Membre confirmé

    Profil pro
    Inscrit en
    Juin 2004
    Messages
    487
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 487
    Points : 455
    Points
    455
    Par défaut
    Dans ce cas, il serait judicieux de savoir quelle valeur de cache pourrait être optimale et si on arrive à approcher l'insertion directe sans utiliser de trigger.
    Je fais deux trois tests pour voir tout cela.

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

Discussions similaires

  1. [11g] Purge de table, trigger et performance
    Par OcterA dans le forum PL/SQL
    Réponses: 2
    Dernier message: 27/08/2014, 18h46
  2. Tester la performance d'un trigger sous SQL Server 2008
    Par lerieure dans le forum MS SQL Server
    Réponses: 8
    Dernier message: 14/02/2011, 19h04
  3. performance trigger SQL2005
    Par maxtin dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 22/08/2010, 19h19
  4. Plusieurs trigger sur une même table / Performances
    Par tchoimars dans le forum PL/SQL
    Réponses: 2
    Dernier message: 27/01/2010, 16h58
  5. [SYBASE ASE 12.5.3] Triggers & performances
    Par lsone dans le forum Sybase
    Réponses: 9
    Dernier message: 11/10/2006, 22h59

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