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

 Firebird Discussion :

Ralentissement lors d'INSERT successifs dans IB 6


Sujet :

Firebird

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 47
    Points : 35
    Points
    35
    Par défaut Ralentissement lors d'INSERT successifs dans IB 6
    Sous Windows 2000 Professionnel, Delphi 7 et Interbase 6 je remplis une Table par des insertions successives à partir d'un fichier texte ( 120 000 lignes environ, autant d'enregistrements).
    La table ne comporte ni constraint ni index (qui seront rajoutés plus tard)
    En début de chargement j'insére environ 20 000 lignes à l'heure, puis les "performances" s'effondrent à 2 000 lignes à l'heure à mi-parcours !
    Pour quelle raison ?
    Comment améliorer -si possible- les choses ?


  2. #2
    Expert éminent
    Avatar de qi130
    Homme Profil pro
    Expert Processus IT
    Inscrit en
    Mars 2003
    Messages
    3 922
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Expert Processus IT
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 3 922
    Points : 6 038
    Points
    6 038
    Par défaut
    Peut-être en commitant de temps en temps !

  3. #3
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut
    Oui il faut commiter régulièrement.
    Par contre 20 000 insertions à l'heure c'est extrèmement lent (ne parlons pas de des 2 000/h).

    Votre serveur est une vielle machine assez lente et/ou vos enregistrements sont très grandes et/ou le serveur et surchargé par d'autres appli qui pompe les resources et/ou vous avez une liaison au serveur via internet ??


    Pour vous donner un ordre de grandeur, sur mon PC qui n'est pas un foudre de guerre, j'insère à plus de 35 000 enregistrements à la minute.
    Avec un entregistrement d'environ 100 octets. Dans une table qui n' a pas d'index/clé. Donc on est bien loin des 20 000 à l'heure Vos insertions se font plus de 100 fois plus lentement .

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 47
    Points : 35
    Points
    35
    Par défaut
    Le fichier de données est en local ainsi que le serveur.
    Ma machine n'est pas trop antédiluvienne (même si elle est fournie par l'administration...)
    Mes enregistrements font 77 caractéres de long ! ( avec une transformation en type entier et une en type date)
    Bref : le commit qui dans mon innocence me paraissait suceptible de ralentir... fait tout l'inverse. J'ai encore bcp à apprendre sur les transactions et les commits !!!
    Je reteste et vous tiens au courant.
    Merci infiniment

  5. #5
    Expert éminent
    Avatar de qi130
    Homme Profil pro
    Expert Processus IT
    Inscrit en
    Mars 2003
    Messages
    3 922
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Expert Processus IT
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 3 922
    Points : 6 038
    Points
    6 038
    Par défaut
    Ne pas faire de commit apporte le confort de pouvoir annuler en cas de problème...

    Le revers de la médaille est la nécessité pour le serveur de garder la trace de toutes les opérations effectuées (pour pouvoir les défaire), mais cela coute en ressources...

  6. #6
    Membre averti

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

    Informations forums :
    Inscription : Décembre 2004
    Messages : 379
    Points : 376
    Points
    376
    Par défaut
    comme dit plus haut essayez un commit tout les 1000 insertions par exemple.

    n'y a t'il pas des triggers qui se déclenchent à chaque insertion?

    si vous insérez aussi massivement, utilisez une table externe puis un insert into select from la table externe, c'est ce qu'il y a de plus rapide.

    bien sur, cela demande plus de programmation, mais le résultat est spéctaculaire!

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 47
    Points : 35
    Points
    35
    Par défaut
    Je n'ai pas trouvé de bonnet d'âne dans les smilies !

    "si vous insérez aussi massivement, utilisez une table externe puis un insert into select from la table externe, c'est ce qu'il y a de plus rapide. "

    dans IBCOnsole :

    CREATE TABLE_PROVISOIRE
    EXTERNAL FILE 'C:\...........'
    (.............
    ..............)

    a fait passer le temps d'insertion d'une douzaine d'heures (INSERTRECORD sous Delphi ) à ... une fraction de seconde ! Eblouissant !

    Puis un INSERT INTO "TABLE_DEFINITIVE" en "CASTANT" en un entier et un Timestamp : moins d'une minute !

    Reste à automatiser cette procédure !

    Mille Mercis aux généreux contributeurs

  8. #8
    Membre averti

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

    Informations forums :
    Inscription : Décembre 2004
    Messages : 379
    Points : 376
    Points
    376
    Par défaut
    un exemple fonctionnel (pour moi!) c'est un script que je balance avec isql
    si cela peux t'aider.

    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
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
     
    SET TERM §;
     
     
    /******************************************************************************
    ***                               nettoyage                                 ***
    ******************************************************************************/
    DROP PROCEDURE STAT_INSERT_STAT_CAB§
    DROP TABLE     STAT_CAB_EXTERNAL§
     
     
     
     
    /******************************************************************************
    ***                 Construction de la table de transfert                   ***
    *******************************************************************************
     
      Cette table doit-être reconstruite à chaque fois pour permettre
      le remplacement du fichier externe!
    */
    CREATE TABLE STAT_CAB_EXTERNAL
    EXTERNAL FILE 'F:\DBSTAT\STAT_CAB_EXTERNAL\STAT_CAB.txt'
    (
      ID                Char( 9),
      CAB               Char(12),
      NumWeek           Char( 4),
      FirstDateWeek     Char(10),
      LastDateWeek      Char(10),
      IDEnseigne        Char( 2),
      IDArt             Char( 7),
      DN                Char( 4),
      MagCount          Char( 4),
      QTRedress         Char( 9),
      CARedress         Char( 9),
      QTBrute           Char( 9),
      CABrute           Char( 9),
      Prior_QT_WRedress Char( 9),
      Prior_CA_WRedress Char( 9),
      Cumul_QTRedress   Char( 9),
      Cumul_CARedress   Char( 9),
      Prior_QT_WBrute   Char( 9),
      Prior_CA_WBrute   Char( 9),
      Cumul_QTBrute     Char( 9),
      Cumul_CABrute     Char( 9),
      QS_PRO            Char( 2)
    )§
     
     
     
     
    /******************************************************************************
    ***                 Construction de la procédure de transfert               ***
    *******************************************************************************
     
      A noter que cette procédure doit-être reconstruite à chaque fois pour
      permettre le remplacement du fichier externe qui contient les nouvelles
      données, ainsi que la table "Stat_CAB_External" ci-dessus
    */
    CREATE PROCEDURE STAT_INSERT_STAT_CAB
    AS
      DECLARE VARIABLE ID                Char( 9);
      DECLARE VARIABLE CAB               Char(12);
      DECLARE VARIABLE NumWeek           Char( 4);
      DECLARE VARIABLE FirstDateWeek     Char(10);
      DECLARE VARIABLE LastDateWeek      Char(10);
      DECLARE VARIABLE IDEnseigne        Char( 2);
      DECLARE VARIABLE IDArt             Char( 7);
      DECLARE VARIABLE DN                Char( 4);
      DECLARE VARIABLE MagCount          Char( 4);
      DECLARE VARIABLE QTRedress         Char( 9);
      DECLARE VARIABLE CARedress         Char( 9);
      DECLARE VARIABLE QTBrute           Char( 9);
      DECLARE VARIABLE CABrute           Char( 9);
      DECLARE VARIABLE Prior_QT_WRedress Char( 9);
      DECLARE VARIABLE Prior_CA_WRedress Char( 9);
      DECLARE VARIABLE Cumul_QTRedress   Char( 9);
      DECLARE VARIABLE Cumul_CARedress   Char( 9);
      DECLARE VARIABLE Prior_QT_WBrute   Char( 9);
      DECLARE VARIABLE Prior_CA_WBrute   Char( 9);
      DECLARE VARIABLE Cumul_QTBrute     Char( 9);
      DECLARE VARIABLE Cumul_CABrute     Char( 9);
     
    BEGIN
     
      FOR
        SELECT ID, CAB, QTRedress, QTBrute
        FROM STAT_CAB_EXTERNAL
        WHERE ( NumWeek = 0 )
          AND ( QTRedress BETWEEN 201 AND 953 )
          AND ( QTBrute   BETWEEN 201 AND 953 )
          AND ( QTRedress < QTBrute           )
      INTO :ID, :CAB, :QTRedress, :QTBrute DO
        DELETE FROM STAT_CAB
        WHERE ( ID  = CAST( :ID  AS Integer ) )
          AND ( CAB =       :CAB              )
          AND ( NOT ( NumWeek BETWEEN CAST( :QTRedress AS Integer )
                                  AND CAST( :QTBrute   AS Integer )
                    )
              );
     
     
      FOR
        SELECT ID, CAB, NumWeek, IDEnseigne
        FROM STAT_CAB_EXTERNAL
        GROUP BY ID, CAB, NumWeek, IDEnseigne
      INTO :ID, :CAB, :NumWeek, :IDEnseigne DO
        DELETE FROM STAT_CAB
        WHERE ( ID         = CAST( :ID         AS Integer  ) )
          AND ( CAB        =       :CAB                      )
          AND ( NumWeek    = CAST( :NumWeek    AS Smallint ) )
          AND ( IDEnseigne = CAST( :IDEnseigne AS Smallint ) );
     
     
      FOR
        SELECT
          ID, CAB,
          NumWeek, FirstDateWeek, LastDateWeek,
          IDEnseigne, IDArt, DN, MagCount,
          QTRedress        , CARedress,
          QTBrute          , CABrute,
          Prior_QT_WRedress, Prior_CA_WRedress,
          Cumul_QTRedress  , Cumul_CARedress,
          Prior_QT_WBrute  , Prior_CA_WBrute,
          Cumul_QTBrute    , Cumul_CABrute
        FROM STAT_CAB_EXTERNAL
        WHERE ( CAST( NumWeek AS Smallint ) BETWEEN 201 AND 953 )
        INTO
          :ID, :CAB,
          :NumWeek, :FirstDateWeek, :LastDateWeek,
          :IDEnseigne, :IDArt, :DN, :MagCount,
          :QTRedress, :CARedress,
          :QTBrute          , :CABrute,
          :Prior_QT_WRedress, :Prior_CA_WRedress,
          :Cumul_QTRedress  , :Cumul_CARedress,
          :Prior_QT_WBrute  , :Prior_CA_WBrute,
          :Cumul_QTBrute    , :Cumul_CABrute
      DO
      BEGIN
     
        INSERT INTO STAT_CAB(
          ID, CAB,
          NumWeek, FirstDateWeek, LastDateWeek,
          IDEnseigne, IDArt, DN, MagCount,
          QTRedress        , CARedress,
          QTBrute          , CABrute,
          Prior_QT_WRedress, Prior_CA_WRedress,
          Cumul_QTRedress  , Cumul_CARedress,
          Prior_QT_WBrute  , Prior_CA_WBrute,
          Cumul_QTBrute    , Cumul_CABrute )
        VALUES(
          :ID, :CAB,
          :NumWeek,
          CAST( :FirstDateWeek AS TIMESTAMP ),
          CAST( :LastDateWeek  AS TIMESTAMP ),
          :IDEnseigne, :IDArt, :DN, :MagCount,
          :QTRedress        , :CARedress,
          :QTBrute          , :CABrute,
          :Prior_QT_WRedress, :Prior_CA_WRedress,
          :Cumul_QTRedress  , :Cumul_CARedress,
          :Prior_QT_WBrute  , :Prior_CA_WBrute,
          :Cumul_QTBrute    , :Cumul_CABrute );
     
      END
     
    END
    §
     
     
     
     
    /******************************************************************************
    ***      Transfert des statistiques "externes" dans la table STAT_CAB       ***
    ******************************************************************************/
    EXECUTE PROCEDURE STAT_INSERT_STAT_CAB§
    COMMIT§
     
     
     
     
    /******************************************************************************
    ***                               Final, nettoyage                          ***
    ******************************************************************************/
    DROP PROCEDURE STAT_INSERT_STAT_CAB§
    DROP TABLE     STAT_CAB_EXTERNAL§
     
     
    EXIT§

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 47
    Points : 35
    Points
    35
    Par défaut
    Superbe exemple... dont je m'empare avec avidité !
    La vie est belle. Merci

  10. #10
    Membre averti

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

    Informations forums :
    Inscription : Décembre 2004
    Messages : 379
    Points : 376
    Points
    376
    Par défaut
    pas de quoi

    n'oubli pas le "résolu"

    bonne chance

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

Discussions similaires

  1. Réponses: 10
    Dernier message: 07/09/2008, 13h38
  2. Réponses: 5
    Dernier message: 22/07/2008, 22h25
  3. Réponses: 2
    Dernier message: 09/06/2008, 21h51
  4. Erreur lors d'insertion dans une table avec Indentity
    Par rad_hass dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 20/03/2008, 15h22
  5. Réponses: 14
    Dernier message: 08/08/2006, 11h31

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