Précédent   Forum des professionnels en informatique > Bases de données > Firebird > SQL
SQL Forum d'entraide sur le SQL pour Firebird
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 24/08/2005, 11h05   #1
Membre éclairé
 
Inscription : décembre 2004
Messages : 379
Détails du profil
Informations forums :
Inscription : décembre 2004
Messages : 379
Points : 304
Points : 304
Par défaut [script sql]

hello,

pour les spécialistes... j'ai un "gros" script sql (plus 300 requetes) qui me sert à extraire des données d'une base.

ce script fonctionne depuis 2 ans environ, mais "bizarrement"...

ainsi, quand je le passe dans une de mes applications qui l'exécute, il passe en environ 1/2 heure à 3 heures en fonction de la machine et du système (linux ou windows) quand le même script passe sur les mêmes machines avec l'utilitaire "isql" il passe en 8 heures environ, voir jusqu'à 3 jours que ce soit sous linux ou windows.

il y a bien sur des "commit" régulier après des insert/update.

le plus marrant et que certaine procédure stockée mettent des heures à "passer", alors qu'une fois arrêté et relancé manuellement ces mêmes procédures passent en quelques minutes.

en fait, lorsque le script est interrompu, puis relancé (sur la commande suivante) cela va vite et lorsqu'il passe d'une traite les requêtes mettent de plus en plus de temps, comme si le serveur s'étouffé avec???

une dernière chose, les resources du système montent très fort au début, lorsque le script démarre et au fur à mesure que les requêtes passent, la charge diminue et bien sur la durée des requêtes augmente???

depuis donc de temps à autre je cherche le pourquoi de temps à autre.

une infos, c'est firebird version 1.5 en classic server qui fonctionne et sous linux et sous windows et les 2 systèmes donnent exactement les mêmes résultats, donc très lent lorsque le script et exécuté en une fois et très rapide lorsqu'une déconnexion/reconnexion et faite entre chaque requête.

quelqu'un à t'il ce problème, existe t'il un paramètre??? une idée, des propositions???

à vous...
jean-jacques varvenne est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/08/2005, 11h23   #2
Membre du Club
 
Inscription : juillet 2005
Messages : 48
Détails du profil
Informations forums :
Inscription : juillet 2005
Messages : 48
Points : 43
Points : 43
essaye de faire une petite sauvegarde juste avant de lancer tes requettes.
rv66 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/08/2005, 14h56   #3
Membre éclairé
 
Inscription : décembre 2004
Messages : 379
Détails du profil
Informations forums :
Inscription : décembre 2004
Messages : 379
Points : 304
Points : 304
cela est fait systématiquement, je recoi un backup, il me faut donc le restaurer (dommage...)

en outre, le scripte commence par retirer tous les index, procédures et triggers inutiliser, cela à fait gagner plus d'un jour de traitement! pour ceux que cela intéresse, voici le code sql qui fait ce "boulot"
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
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
SET TERM §;
 
 
 
        /******************************************************************************
        *** DESTRUCTIONS DE TOUS LES TRIGGERS, PROCEDURES, TABLES ET INDEX INUTILES ***
        ******************************************************************************/
 
CREATE PROCEDURE DROP_FOR_GEN_DAT
AS
  DECLARE VARIABLE TableName      VarChar(32);
  DECLARE VARIABLE ConstraintName VarChar(32);
  DECLARE VARIABLE IndexName      VarChar(31);
  DECLARE VARIABLE IsLoop         Integer;
  DECLARE VARIABLE CountLoop      Integer;
BEGIN
 
  /********************************************************************
  *** Passe à la trappe tous les "foreign key"                      ***
  ********************************************************************/
  FOR
    SELECT
      RDB$Relation_Name, RDB$Constraint_Name
    FROM RDB$Relation_Constraints
    WHERE RDB$Constraint_Type = 'FOREIGN KEY'
  INTO :TableName, :ConstraintName DO
  BEGIN
    EXECUTE STATEMENT 'ALTER TABLE ' || TableName || ' DROP CONSTRAINT ' || ConstraintName;
  END
 
 
 
 
  /********************************************************************
  *** Passe à la trappe tous les "CHECK"                            ***
  ********************************************************************/
 
  FOR
    SELECT
      RDB$Relation_Name, RDB$Constraint_Name
    FROM RDB$Relation_Constraints
    WHERE RDB$Constraint_Type = 'CHECK'
  INTO :TableName, :ConstraintName DO
  BEGIN
    EXECUTE STATEMENT 'ALTER TABLE ' || TableName || ' DROP CONSTRAINT ' || ConstraintName;
  END
 
 
 
 
  /********************************************************************
  *** Passe à la trappe tous les "TRIGGERS"                         ***
  ********************************************************************/
 
  FOR
    SELECT
      RDB$Trigger_Name
    FROM RDB$Triggers
    WHERE RDB$Flags = 1
  INTO :ConstraintName DO
  BEGIN
    EXECUTE STATEMENT 'DROP TRIGGER ' || ConstraintName;
  END
 
 
 
 
  /********************************************************************
  *** Passe à la trappe toutes les "PROCEDURES"                     ***
  ********************************************************************/
 
  /* Le problème est de régler les interdépendances!
     Pour cela, la boucle est appelée sans cesse jusqu'au
     moment ou plus aucune procédure n'est détruite!
  */
 
  IsLoop    = 1;
  CountLoop = 25;
 
  WHILE( ( IsLoop = 1 ) AND ( CountLoop > 0 ) ) DO
  BEGIN
 
    IsLoop = 0;
 
    FOR
      SELECT
        RDB$Procedure_Name
      FROM RDB$PROCEDURES
      WHERE RDB$Procedure_Name != 'DROP_FOR_GEN_DAT'
    INTO :ConstraintName DO
    BEGIN
 
      EXECUTE STATEMENT 'DROP PROCEDURE ' || ConstraintName;
      IsLoop = 1;
 
      WHEN ANY DO
        IsLoop = 1;
 
    END
 
    CountLoop = CountLoop - 1;
 
  END
 
 
 
 
  /********************************************************************
  *** Passe à la trappe toutes les "TABLES"                         ***
  ********************************************************************/
 
  FOR
    SELECT
      RDB$Relation_Name
    FROM RDB$RELATIONS
    WHERE ( ( RDB$SYSTEM_FLAG = 0 ) OR ( RDB$SYSTEM_FLAG IS NULL ) )
      AND NOT ( RDB$Relation_Name IN
                ( 'DISQUES', 'GENRE', 'ARTISTE', 'TRACKLIST',
                  'CRITIQUES', 'INTERDITS', 'STOCK', 'PRIX',
                  'DISTRI', 'TYPSUPPORT'
                )
              )
  INTO :TableName DO
  BEGIN
    EXECUTE STATEMENT 'DROP TABLE ' || TableName;
  END
 
 
 
 
  /********************************************************************
  *** Passe à la trappe tous les index de DISQUES                  ***
  ********************************************************************/
 
  FOR
    SELECT RDB$INDEX_NAME FROM RDB$INDICES
    WHERE RDB$RELATION_NAME = 'DISQUES'
      AND NOT ( RDB$INDEX_NAME IN
                 ( 'ID_UNIQUE'       ,
                   'DISQUES_AUTEUR'  , 'DISQUES_REGROUPEMENT',
                   'DISQUES_ORIGINE' , 'DISQUES_CODEPRIX'    ,
                   'DISQUES_TITRE'   , 'DISQUES_CODEFORMAT'  ,
                   'DISQUES_ISEXPORT', 'DISQUES_DISTRIBUTEUR'
                 )
              )
  INTO :IndexName DO
  BEGIN
    EXECUTE STATEMENT 'DROP INDEX ' || IndexName;
 
 
    WHEN ANY DO
      IsLoop = 1; --juste pour la place
 
  END
 
 
END
§
 
EXECUTE PROCEDURE DROP_FOR_GEN_DAT§
COMMIT§
 
DROP PROCEDURE DROP_FOR_GEN_DAT§
COMMIT§
bien sûr, les noms des tables et index sont à changer!!!

truc très con, toujours utiliser une copie!!! dans le cas contraire, sorter un drap et pleurer à chaudes larmes si vous n'avez de backup...

il ne faut que quelques secondes pour détruire toutes les tables, index et autre d'une base de données...

il faut dire que la base de données en question à 237 tables, 124 procédures et un millier d'index! donc le ménage me fait gagner un temp considérable.

les procédures qui "bloques" sont typiquement des procédures contenant une boucle "FOR" et dont le corps effectue un "UPDATE" ce mécanisme bien que curieux et infiniment plus rapide que de faire un UPDATE avec un ou plusieurs SELECT pour obtenir les données à placer dans les champs.

ceci et la cause directe que firebird n'utilise pas les index pour les "sous-select". ce type de procédure contourne donc ce problème.

ici, je m'apprête à refaire un test en ménagant une pause de 5 secondes entres les requêtes (après déconnexion), histoire de "voir" si le nombre de fb_inet_server qui semble être le problème.

en effet, j'ai constaté que la connexion/déconnexion entres chaques requêtes accélères les choses un certain temps, mais à chaque reconnexion une instance fb_inet_server apparait, donc là, il y a surement un os.

c'est probablement la piste à creuser???
jean-jacques varvenne est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 12h26.


 
 
 
 
Partenaires

Hébergement Web