Précédent   Forum des professionnels en informatique > Bases de données > MySQL > SQL Procédural
SQL Procédural Forum d'entraide sur les triggers, les procédures stockées et les fonctions en MySQL
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 13/03/2006, 10h05   #1
Membre régulier
 
Inscription : mai 2004
Messages : 121
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 121
Points : 79
Points : 79
Par défaut Group by sur plusieurs table de même squelette

Bonjour à tous,

Je vais exposer mon problème clairement :

J'ai des enregistrements présents dans des fichiers( ayant le même formatage ) que je dois lire afin de mettre à jour une table principale.

Les fichiers étant assez volumineux, j'utilise la fonction MySQL LOAD DATA INFILE pour chaque fichier dans une table TMP.

Jusque là, pas de problème.

Maintenant, lors du contrôle des données( c'est à dire apres que tout les LOAD DATA INFILE soient passés), je dois connaitre la ligne et le nom du fichier(non présent dans la table et ni dans le formatage du fichier) qui a présenté un défaut.

Donc dans ma table TMP, j'ai ajouté un champ ligne avec un auto-increment pour connaitre la ligne qui pose probleme. Pour un fichier, ca fonctionne mais pour deux, l'auto-increment reprends normalement à la suite du dernier enregistrement(soit la derniere ligne du fichier précédent).

Je me suis dis, tiens je vais faire plusieurs table temporaire avec le même squelette que ma table TMP(que je nommerai différemment via PHP). Exemple :
Code :
1
2
3
4
5
6
7
8
9
`tmp1` (
  `ligne` int(11) NOT NULL AUTO_INCREMENT,
  `file` varchar(30) DEFAULT '0',
  `unite` varchar(10) DEFAULT '0',
  `indicateur` varchar(4) DEFAULT '0',
  `colonne` char(1) DEFAULT '0',
  `nombre` double DEFAULT '0',
  PRIMARY KEY  (`ligne`),
) ENGINE=MyISAM DEFAULT CHARSET=latin1
Code :
1
2
3
4
5
6
7
8
9
`tmp2` (
  `ligne` int(11) NOT NULL AUTO_INCREMENT,
  `file` varchar(30) DEFAULT '0',
  `unite` varchar(10) DEFAULT '0',
  `indicateur` varchar(4) DEFAULT '0',
  `colonne` char(1) DEFAULT '0',
  `nombre` double DEFAULT '0',
  PRIMARY KEY  (`ligne`),
) ENGINE=MyISAM DEFAULT CHARSET=latin1
etc...

C'est une idée, pourquoi pas, et je pose maintenant ma question :

Dans ma table TMP(seule à l'origine), j'utilisait un GROUP BY afin de connaitre la somme de tous les nombres avec le même indicateur, même colonne et même unité. Est il possible de refaire la même opération avec ce nouveau concept ? Sinon est il possible de "concaténer" plusieurs table de même squelette pour n'en faire qu'une ?

Merci beaucoup par avance
hackrobat est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/03/2006, 11h11   #2
Rédacteur
 
Avatar de pcaboche
 
Homme Pierre Caboche
Inscription : octobre 2005
Messages : 2 197
Détails du profil
Informations personnelles :
Nom : Homme Pierre Caboche
Âge : 32
Localisation : Singapour

Informations forums :
Inscription : octobre 2005
Messages : 2 197
Points : 4 727
Points : 4 727
Bon, plusieurs choses:

1) tu aurais peut-être meilleur temps d'écrire un petit programme qui te rajoute les numéros de ligne dans tes fichiers

2) sinon, tu enlèves la contrainte PRIMARY KEY (`ligne`) et entre 2 chargement de fichiers, tu remets le AUTO_INCREMENT à 1 (ALTER TABLE...). A essayer, je ne sais pas si ça marche.


Du coup, tu n'as plus besoin de faire un GROUP BY sur 2 tables, mais je vais quand même répondre à la question :

3) soit tu fais un:
Code :
1
2
3
4
5
6
7
SELECT ...
FROM
  ( SELECT ...
   UNION ALL
    SELECT ...) A
 
GROUP BY A.???
mais c'est lourd et MySQL >=4.1

4) soit tu fais une MERGE TABLE puisque tes tables sont en MyISAM


Je préfère la solution 2
pcaboche est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/03/2006, 12h08   #3
Membre régulier
 
Inscription : mai 2004
Messages : 121
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 121
Points : 79
Points : 79
Salut Pcaboche,

Merci pour ton intervention.

pour ta solution 1, je la mets de coté car elle sera la solution de dernier recours

Pour la deux, je viens d'essayer mais ca ne marche pas du au auto_increment lié forcément à un primary key donc unique

Pour la 3 et 4, ca pourrait faire l'affaire, merci beaucoup en tout cas pour ton intervention.

a+
hackrobat est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/03/2006, 13h14   #4
Rédacteur
 
Avatar de pcaboche
 
Homme Pierre Caboche
Inscription : octobre 2005
Messages : 2 197
Détails du profil
Informations personnelles :
Nom : Homme Pierre Caboche
Âge : 32
Localisation : Singapour

Informations forums :
Inscription : octobre 2005
Messages : 2 197
Points : 4 727
Points : 4 727
Comme indiqué plus haut, j'avais de sérieux doutes par rapoort à la 2.

Ravi de t'avoir aidé.
pcaboche est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/03/2006, 16h40   #5
Membre régulier
 
Inscription : mai 2004
Messages : 121
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 121
Points : 79
Points : 79
Citation:
Envoyé par pcaboche
4) soit tu fais une MERGE TABLE puisque tes tables sont en MyISAM
C'est la solution retenue, merci encore
hackrobat est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/03/2006, 16h49   #6
Rédacteur
 
Avatar de pcaboche
 
Homme Pierre Caboche
Inscription : octobre 2005
Messages : 2 197
Détails du profil
Informations personnelles :
Nom : Homme Pierre Caboche
Âge : 32
Localisation : Singapour

Informations forums :
Inscription : octobre 2005
Messages : 2 197
Points : 4 727
Points : 4 727
Je viens de penser à une autre solution si tu as de nombreux fichiers (parce que créer autant de tables que de fichiers, c'est peut-être un peu lourd):

Tu aurais 2 tables: tmp1 (avec AUTO_INCREMENT) et tmp2 (avec AUTO_INCREMENT)

tu fais :
- un LOAD DATA INFILE dans tmp1 (ça t'incrémente la ligne)
- un :
Code :
1
2
INSERT INTO tmp2
SELECT * FROM tmp1
- un TRUNCATE TABLE tmp1 (vide la table, remet l'AUTO_INCREMENT à 1)
- tu recommences la manoeuvre avec un autre fichier

Comme ça, t'as tous les enregistrements dans tmp2, avec les bons numéros de ligne (qui n'est donc plus vraiment une table temporaire)
pcaboche est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/03/2006, 18h12   #7
Membre régulier
 
Inscription : mai 2004
Messages : 121
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 121
Points : 79
Points : 79
Citation:
Envoyé par pcaboche
Je viens de penser à une autre solution si tu as de nombreux fichiers (parce que créer autant de tables que de fichiers, c'est peut-être un peu lourd):

Tu aurais 2 tables: tmp1 (avec AUTO_INCREMENT) et tmp2 (avec AUTO_INCREMENT)

tu fais :
- un LOAD DATA INFILE dans tmp1 (ça t'incrémente la ligne)
- un :
Code :
1
2
INSERT INTO tmp2
SELECT * FROM tmp1
- un TRUNCATE TABLE tmp1 (vide la table, remet l'AUTO_INCREMENT à 1)
- tu recommences la manoeuvre avec un autre fichier

Comme ça, t'as tous les enregistrements dans tmp2, avec les bons numéros de ligne (qui n'est donc plus vraiment une table temporaire)
Cela revient à faire directement un INSERT INTO. En PHP, tu lis la ligne une par une et tu l'inseres dans TMP avec le bon numero de ligne, ce qui fait utiliser une seule table.

Pour te prouver pourquoi je reste sur le LOAD INTO FILE avec une MERGE, sur la version précedente, le script mettais 40min à s'executer. Maintenant, je mets 7min

Il ne faut pas oublier que le LOAD INTO FILE est 20x plus rapide qu'un INSERT.

Merci encore, bonne soirée à toi

Kev

Je pense rester sur cette version si tous les tests s'avèrent positifs
hackrobat est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/03/2006, 19h41   #8
Rédacteur
 
Avatar de pcaboche
 
Homme Pierre Caboche
Inscription : octobre 2005
Messages : 2 197
Détails du profil
Informations personnelles :
Nom : Homme Pierre Caboche
Âge : 32
Localisation : Singapour

Informations forums :
Inscription : octobre 2005
Messages : 2 197
Points : 4 727
Points : 4 727
Citation:
Envoyé par hackrobat
Cela revient à faire directement un INSERT INTO. En PHP, tu lis la ligne une par une et tu l'inseres dans TMP avec le bon numero de ligne, ce qui fait utiliser une seule table.
Si tu fais des insertions de lignes 1 par 1, oui ça met du temps (parce que les index sont mis à jour à chaque fois), mais si tu fais une insertion en bloc (INSERT ... SELECT), c'est beaucoup plus rapide (les index sont mis à jour en une seule fois: à la fin)

Essaye et tu verras...
pcaboche 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 22h09.


 
 
 
 
Partenaires

Hébergement Web