[MySQL] Taille du fichier temporaire

Discutez d'informatique ici !
Alpha
Membre Complexe
Messages: 2176
Enregistré le: 21 Mai 2005, 12:00

[MySQL] Taille du fichier temporaire

par Alpha » 04 Aoû 2009, 14:33

Bonjour,

Je débute le MySQL et j'ai un problème avec la taille (trop grosse) des fichiers temporaires créés par une requête simple, mais avec un fichier qui fait 15 millions de lignes (fichier texte de base de 1 Go).

Voici une description plus précise du problème :

J'exécute en fait la requête suivante :

INSERT INTO table2
SELECT Champ1, Champ2, CONCAT(Champ3, Champ4), Sum(Champ5)
FROM table1
GROUP BY Champ1, Champ2, CONCAT(Champ3, Champ4), Left(Champ1,2)
HAVING (((Left(Champ1,2))="expr1" or (Left(Champ1,2))="expr2"));

qui insère dans la table2 les champs de table1, en concaténant deux de ces champs, en regroupant selon les champs 1 et 2 et en sommant sur le dernier champ.

La table1 fait compte 15 millions de lignes et fait 1 Go, ce qui est certes beaucoup. Cependant, est-il normal que la requête créé un fichier temporaire de plus de 20 Go et tourne plus de 2H?

J'ai cherché à voir si la modification des paramètres dans MySQL admin pouvaient régler la chose, mais il y a tellement de paramètres que je m'y perds un peu. J'ai vu entre autres des paramètres tels que lock size, max heap size, max sort file size, mais j'ignore lequel est le bon (et en augmentant trop un de ces paramètres j'ai fait planter le PC dont la mémoire vive était bouffée par un "truc-size", PC qui n'a bien remarché qu'au 2ème redémarrage :zen:).

Il me semble que cette requête est simple et que ce qui se produit n'est pas normal. Avez-vous une idée de ce qui peut clocher?

Merci.

Cordialement



nemo67
Messages: 7
Enregistré le: 04 Aoû 2009, 20:08

par nemo67 » 04 Aoû 2009, 21:24

Bonjour,

je sais pas si c'est normal mais votre requête me semble "bizarre"

INSERT INTO table2
SELECT Champ1, Champ2, CONCAT(Champ3, Champ4), Sum(Champ5)
FROM table1
GROUP BY Champ1, Champ2, CONCAT(Champ3, Champ4), Left(Champ1,2)
HAVING (((Left(Champ1,2))="expr1" or (Left(Champ1,2))="expr2"));


le having s'utilise pour exprimer des conditions sur des agregats or là c'est juste un filtre sur des valeurs non calculées. J'aurai mis

Je ne comprends pas non plus le Left(Champ1,2) à la fin du group by. Normalement cela reprend les champs du select qui se trouvent avant les colonnes d'agrégation ?

INSERT INTO table2
SELECT Champ1, Champ2, CONCAT(Champ3, Champ4), Sum(Champ5)
FROM table1
WHERE Left(Champ1,2) in ("expr1", "expr2")
GROUP BY Champ1, Champ2, CONCAT(Champ3, Champ4)

Si en plus vous avez défini un index sur champ1 (voire champ2) cela devrait aller mieux je pense

Alpha
Membre Complexe
Messages: 2176
Enregistré le: 21 Mai 2005, 12:00

par Alpha » 04 Aoû 2009, 22:19

Merci beaucoup, je vais regarder ça.

Le Left(Champ1, 2) est là pour désigner les 2 premiers caractères du champ1, je ne sais pas si cela répond à votre question.

Comme je découvre MySQL, je ne sais pas encore trop comment utiliser les index, j'ai vu qques pages là-dessus mais j'ai trouvé les informations assez vagues.

Pour l'instant j'en suis à me poser les questions suivantes :

Où et comment créé-t-on les index? En éditant les tables et en cochant la case Index (qui est déjà cochée pr moi) ou en définissant une clé primaire, ou... ?

Un ami m'a aussi à juste titre fait remarquer que, tout comme on utilise dans Access des requêtes sélection dans d'autres requêtes comme si c'étaient des tables (en fait la requête désigne aussi le résultat de la requête du coup), on peut sous MySQL se contenter de faire une requête sélection pour faire appel à elle plus loin dans une autre requête, ce qui évite donc de passer par l'INSERT dans une autre table. Je sais pas si j'ai été très clair.

Mais je vais creuser ça ;)

Benjamin
Membre Complexe
Messages: 2337
Enregistré le: 14 Avr 2008, 11:00

par Benjamin » 05 Aoû 2009, 06:40

Fichier texte de 1Go :doh: C'est de la donnée ça lol. Rien que pour lire le fichier, il doit falloir pas mal de temps ^^
Sinon, j'y connais rien du tout en MySQL, donc je vais rien pouvoir te dire.

Alpha
Membre Complexe
Messages: 2176
Enregistré le: 21 Mai 2005, 12:00

par Alpha » 05 Aoû 2009, 08:56

Benjamin a écrit:Fichier texte de 1Go :doh: C'est de la donnée ça lol. Rien que pour lire le fichier, il doit falloir pas mal de temps ^^


En effet, d'ailleurs MySQL refuse de m'afficher la table en entier. Si quelqu'un connaît le paramètre à régler pour qu'il l'affiche en entier...

J'ai déjà avancé sur un petit point : l'insertion est inutile dans ma requête, il me suffit de faire une requête sélection, mais sous forme de Vue (View) afin que cette requête sélection puisse être utilisée comme une table dans une autre requête (d'ailleurs une vue est stockée au même endroit que les tables).

nemo67
Messages: 7
Enregistré le: 04 Aoû 2009, 20:08

par nemo67 » 05 Aoû 2009, 21:57

Le Left(Champ1, 2) est là pour désigner les 2 premiers caractères du champ1, je ne sais pas si cela répond à votre question.
Pas vraiment, j'ai bien vu que le left donnait les x caractères à gauche. Par contre c'est l'association avec le group by que je ne comprennais pas.

Exemple : select Ville, sum(Montant) from Ventes group by Ville --> je comprend : cela donne le montant total des ventes ville par ville

et vous vous avez écrit select ville, sum(Montant) from ventes group by ville, arrondissement --> vous allez avoir le montant total des ventes par VILLE ET ET ARRONDISSEMENT mais vous n'afficherez que les VILLES. syntaxiquement c'est correct, mais est ce que vous attendez cela ?

Les index permettent d'accélerer les traitements en évitant de lire la table tout entière. C'est d'autant plus efficace que la table est important. Idéalement il faut une clé primaire avec un numéro unique par ligne + des index sur les champs pour lesquels on fait des filtres -> champ1 chez vous.

Sinon oui votre ami à raison vous pouvez utiliser une syntaxe du style

select * from (select * from table1)

Alpha
Membre Complexe
Messages: 2176
Enregistré le: 21 Mai 2005, 12:00

par Alpha » 06 Aoû 2009, 01:25

Je comprends la remarque pour ville et arrondissement, la logique veut en effet que je mette également le Left(Champ1,2) dans le Select, ou alors que je ne le mette pas dans le group by ;)

Pour le SELECT* FROM (SELECT* FROM table1), je vais tenter ça.

Merci.

PS : cette fois l'heure du message ne correspond pas vraiment à un insomnie, mais (si vous voulez rire) à ce qui s'appelle "s'allonger 1H après être rentré du boulot et se réveiller à 2H15 du mat" :ptdr:

 

Retourner vers ϟ Informatique

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 5 invités

Tu pars déja ?



Fais toi aider gratuitement sur Maths-forum !

Créé un compte en 1 minute et pose ta question dans le forum ;-)
Inscription gratuite

Identification

Pas encore inscrit ?

Ou identifiez-vous :

Inscription gratuite