Vous n'êtes pas identifié(e).
Pages : 1
Bonjour,
alors, mon problème d'aujourd'hui est de pouvoir incrémenter un fichier csv. En effet, je ne peux pas créer le fichier d'un seul coup car ma requête dépasse la mémoire de mon serveur. Je voudrais alors "découper" ma requête et ainsi copier le résultat de chacune d'entre elle dans un seul et unique fichier csv.
Est ce possible ? et si oui comment ?
J'ai essayé de regarder du coté de la fonction COPY mais je ne vois rien qui se rattache à ma demande !!
Merci de votre aide,
Cordialement
RB
Hors ligne
Le résultat de la requête dépasse la taille du serveur ? ça ne devrait pas gêner pour un copy (la raison d'être à court de mémoire, c'est le processus de pagination dans psql je pense). Il m'arrive régulièrement de faire des copy générant des fichiers de plusieurs centaines de Go, sans souci de mémoire.
Si je suis à côté de la plaque, merci de détailler davantage le problème, avec un exemple, que je puisse t'aider plus efficacement.
Dernière modification par Marc Cousin (15/09/2009 11:29:25)
Marc.
Hors ligne
Merci pour ce début de réponse.
En fait je travaille beaucoup (et exclusivement) avec pgadmin et quand et lance ma requête (sans le COPY), le serveur me répond au bout d'un moment :
ERREUR: n'a pas pu écrire le bloc 7134534 du fichier temporaire : No space left on device
HINT: Peut-être manquez-vous de place disque ?
ma requête est une multiplication entre 2 deux tables l'une faisant 176 millions de lignes et l'autre 4000 lignes : le résultats de la requête devrait faire 6 millions de lignes (agrégation des valeurs multipliées)
Je pense que le stockage en mémoire (ou sur le disque???) de la requête est trop grosse !!
si vous avez des idées ou si il faut que je dise des choses plus précises, dites le moi sans problème !!
RB
Hors ligne
On parle de générer 500 milliards d'enregistrements et les trier ensuite. Le système, pour un tel volume, doit faire un tri disque. Et n'a pas la place. On n'en est même pas à la phase d'envoi du CSV, simplement à la génération du résultat.
Je ne suis pas sûr qu'un SGBD soit l'endroit idéal pour faire ce genre de traitements, mais pourquoi faire le produit cartésien, puis l'unicité. Pourquoi pas d'abord l'unicité sur les 2 tables de départ puis le produit cartésien ? Le résultat devrait être identique, mais les volumes à traiter infiniment plus petits.
Marc.
Hors ligne
Ok merci.
donc je reviens à la question du départ : est il possible d'incrémenter des fichier csv ?
RB
ps : l'unicité avant la multiplication n'est pas possible à cause des relations entre les deux tables.
Hors ligne
Ça ne résoudra pas le problème : il faut que postgres ait traité TOUS les enregistrement (pour faire le distinct) avant de pouvoir retourner ne serait ce qu'une ligne pour le CSV
Marc.
Hors ligne
Pas si je découpe ma requête en plusieurs sous requêtes :
soit tb1, et tb2 les tables originales
select T1.a, sum(T1.b*T2.c)
from (select a, b from tb1 where a=e) T1, (select c, d from tb2 where d=e) T2
where T1.a=T2.d
et si je fais ça autant de fois que de valeurs e différentes. Cela devrait me donner 80 fichiers csv. Je pourrais les concaténer avec d'autres outils que postgresql mais si celui permet de rajouter des lignes à un fichier csv existant cela m'éviterait de passer par 15 outils différents.
merci
RB
Hors ligne
Ok, donc la question initiale est de faire un append sur un fichier CSV déjà commencé ? Le mieux c'est peut être de faire un COPY to stdout avec psql, et faire la concaténation par >> dans un shell ?
Ce que je veux dire, c'est lancer une série de commandes psql -e 'COPY ... TO STDOUT' >> mon_fichier_resultat.csv
Marc.
Hors ligne
OK et merci pour les réponses.
Question subsidiaire :
est ce possible avec pgadmin III car je ne suis vraiment pas à l'aise avec psql.
RB
Hors ligne
Je ne sais pas si cela va correspondre exactement à votre soucis mais j'ai eû un cas similaire à traiter en PHP et j'ai lu mes données par paquets en utilisant LIMIT et OFFSET.
Par exemple: SELECT t1,t2 FROM table LIMIT 5000 OFFSET 0;
Bien sûr cela était facile en PHP puisque j'ai fait un boucle en incrémentant les valeurs de LIMIT et OFFSET.
Est-ce possible sous pgadmin.
Dernière modification par jpp (16/09/2009 10:48:11)
Hors ligne
Ça risque surtout d'être très coûteux : comme la requête comporte un distinct, elle aura (presque) le coût total à chaque itération, malgré le limit.
Pour répondre à la question initiale :
Ce n'est à mon avis pas possible avec pgadminIII (gleu ?).
De toutes façons, si c'est pour automatiser le traitement, cela sera beaucoup plus facile avec psql (on peut facilement l'utiliser dans un script)
Dernière modification par Marc Cousin (16/09/2009 11:52:51)
Marc.
Hors ligne
Je me posais la question si PostGres chargeait tous les enregistrements sur chacunes des requêtes "LIMIT ...OFFSET"; d'après ce que vous me dites c'est OUI.
Mais je ne comprends pas pourquoi cela a résolu mon problème ?
Dommage que cela ne fasse pas avancer notre collègue....
Hors ligne
Il calcule tout ce qui est nécessaire pour retourner les enregistrements d'offset à offset + limit (donc du premier à offset+limit, mais il vire tous les enregistrements jusqu' à offset -1)
Ça dépend donc fortement du plan nécessaire pour retourner ces enregistrements. Un distinct par exemple force la dernière étape du plan à être un tri. À partir de là, il faut traiter tous les enregistrements.
Marc.
Hors ligne
Pages : 1