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

PostgreSQL Discussion :

[Projet Master2] Import de données en masse pour application statistique


Sujet :

PostgreSQL

  1. #1
    Membre régulier
    Inscrit en
    Mai 2007
    Messages
    149
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 149
    Points : 89
    Points
    89
    Par défaut [Projet Master2] Import de données en masse pour application statistique
    Bonjour,
    pour mon projet de fin d'étude de Master Informatique, je dois réaliser une application qui permet de charger des fichiers historiques concernant l'année 2007, sur trois départements. Il faut compter 20 000 lignes par fichier, pour 12 mois.
    12 x 3 x 20 000 je vous laisse imaginer la quantité de données à charger.
    La création de clé primaire en amont étant anarchique (et buggée ? Je précise que je ne peut rien faire à ce niveau), il arrive de retrouver plusieurs fois la meme clé sur le meme département ou d'un département à l'autre, ma clé primaire est donc composée du numéro d intervention (entier), de l'id du departement(varchar 2 caractères mais je n'ai pas défini cette limite) ainsi que d'un autre champ unique trouvé (varchar non limité).
    Au début de l'importation je ma clé primaire n'était composée que de deux champs, et je trouvai que l'importation par COPY FROM etait assez rapide malgré la quantité de données. J'ai du ajouter un troisième champ, et depuis c'est de plus en plus lent et je me trouve confronté a des timeout (max 30 sec of execution sur php).

    J'aimerai votre avis, puis-je supprimer la clé primaire ? Cela va il impacter la rapidité de mon script (en bien)? Ou dois-je créer une nouvelle clé primaire pour remplacer cette clé composite ?

    De manière plus générale, j'aimerais que vous me conseillez sur les bonne pratiques à suivre pour la mise en place et la bonne utilisation d'une telle base.

    Merci à ceux qui seront arrivés jusqu'au bout de ce message, ce fut long mais j'ai tenté de décrire au mieux le contexte de la mise en place.

  2. #2
    Membre expérimenté Avatar de scheu
    Inscrit en
    Juin 2007
    Messages
    1 506
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 1 506
    Points : 1 734
    Points
    1 734
    Par défaut
    Pour des perfs optimales, c'est mieux de ne pas avoir de clé primaire sur la table, mais attention à ne pas insérer de doublons ;-)
    La théorie, c'est quand on sait tout mais que rien ne fonctionne.
    La pratique, c'est quand tout fonctionne mais que personne ne sait pourquoi.
    Ici, nous avons réuni théorie et pratique : Rien ne fonctionne ... et personne ne sait pourquoi !

    Réplication de base avec Postgresql : http://scheu.developpez.com/tutoriel.../log-shipping/

  3. #3
    Membre régulier
    Inscrit en
    Mai 2007
    Messages
    149
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 149
    Points : 89
    Points
    89
    Par défaut
    Ah, oui je n'y avai pas pensé, il y a le risque d'insérer des doublons.
    Donc que me conseilles tu ?

    L'absence de clé primaire permet elle aussi d'améliorer les performances au niveau des COUNT ?

  4. #4
    Membre expérimenté Avatar de scheu
    Inscrit en
    Juin 2007
    Messages
    1 506
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 1 506
    Points : 1 734
    Points
    1 734
    Par défaut
    Non l'absence de clé primaire améliore les perfs juste pour les insert et update, car à chaque fois il contrôle justement avant de modifier s'il n'y a pas de doublons, ce qui peut être coûteux pour de gros volumes
    Une clé primaire crée aussi implicitement un index qui est mis à jour à chaque modif (insert/update/delete) qui peut être coûteux aussi

    Sur les select, les PK peuvent même améliorer les perfs car postgresql utilisera peut être l'index si le select ne ramène pas trop de lignes
    Regarde la doc sur l'optimiseur Postgresql avec notamment le calcul des stats et les plans d'exécution
    La théorie, c'est quand on sait tout mais que rien ne fonctionne.
    La pratique, c'est quand tout fonctionne mais que personne ne sait pourquoi.
    Ici, nous avons réuni théorie et pratique : Rien ne fonctionne ... et personne ne sait pourquoi !

    Réplication de base avec Postgresql : http://scheu.developpez.com/tutoriel.../log-shipping/

  5. #5
    Membre régulier
    Inscrit en
    Mai 2007
    Messages
    149
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 149
    Points : 89
    Points
    89
    Par défaut
    Après avoir fait quelques tests, je peux parler plus en détail des performances au niveau des requêtes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    select count("No INTERVENTION"),"CODE_INTERVENTION",e."SECTEUR","DATE IT" 
    from histo h 
    JOIN "ETL" e on h."ILOT"=e."UI" 
    and h."BASE_GPC"=e."BASE_GPC" 
    and "DATE IT" between '01/05/2007' and '31/05/2007' and h."BASE_GPC"='1G' group by "DATE IT","CODE_INTERVENTION",e."SECTEUR" ORDER BY "SECTEUR","CODE_INTERVENTION";
    Une requête comme celle-ci prend en moyenne 90 secondes pour s'exécuter (je précise qu'il y a 37 000 lignes estimées), est-ce normal ou y'a t'il des choses que je puisse faire pour en améliorer les performances?

    Pour scheu, j'ai lu le document et d'apres le explain la première opération qu'il fait est un 'group agrégate', et il fait les filter (clause where) lors des dernière opérations. J'ai vaguement souvenir d'un cours de licence ou l'on parlait d'optimisation des requêtes en commencant par faire les clauses where mais dans ce cas précis j'aurai besoin d'un coup de pouce.

  6. #6
    Membre expérimenté Avatar de scheu
    Inscrit en
    Juin 2007
    Messages
    1 506
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 1 506
    Points : 1 734
    Points
    1 734
    Par défaut
    Quelles sont les volumétries (nb de lignes) de tes tables, et le nb de lignes retournées par ta requête ?
    Les stats sur ces 2 tables sont-elles à jour ?
    As-tu des indexes sur ces 2 tables ? Sur quelles colonnes ?
    Mets-nous le résultat de "explain ta_requete;"
    La théorie, c'est quand on sait tout mais que rien ne fonctionne.
    La pratique, c'est quand tout fonctionne mais que personne ne sait pourquoi.
    Ici, nous avons réuni théorie et pratique : Rien ne fonctionne ... et personne ne sait pourquoi !

    Réplication de base avec Postgresql : http://scheu.developpez.com/tutoriel.../log-shipping/

  7. #7
    Membre régulier
    Inscrit en
    Mai 2007
    Messages
    149
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 149
    Points : 89
    Points
    89
    Par défaut
    • Table histo : 37 000 lignes estimées ( non comptées)
    • etl : 240 lignes comptées

    Pour les stats : j'ai fai un vacuum analyse tel que postgres m'a conseillé, mais je n'ai pa vu la différence et postgres ne m'a pa suggéré de creer un index. Peut être que je n'ai pas vu ?
    • La table histo à un index sur No Intervention, Base_gpc et liste_a (colonne non utilisée dans cette requete)
    • la table etl n'a pas d'index.



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    "GroupAggregate  (cost=59869.42..60033.69 rows=6571 width=40)"
    "  ->  Sort  (cost=59869.42..59885.85 rows=6571 width=40)"
    "        Sort Key: e."SECTEUR", h."CODE_INTERVENTION", h."DATE IT""
    "        ->  Hash Join  (cost=9.44..59452.76 rows=6571 width=40)"
    "              Hash Cond: ((h."ILOT")::text = (e."UI")::text)"
    "              ->  Seq Scan on histo h  (cost=0.00..59300.69 rows=12307 width=41)"
    "                    Filter: (("DATE IT" >= '2007-05-01'::date) AND ("DATE IT" <= '2007-05-31'::date) AND (("BASE_GPC")::text = '1G'::text))"
    "              ->  Hash  (cost=7.99..7.99 rows=116 width=25)"
    "                    ->  Seq Scan on "ETL" e  (cost=0.00..7.99 rows=116 width=25)"
    "                          Filter: ('1G'::text = ("BASE_GPC")::text)"
    Voila! je te remercie pour ton aide.

  8. #8
    Membre expérimenté Avatar de scheu
    Inscrit en
    Juin 2007
    Messages
    1 506
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 1 506
    Points : 1 734
    Points
    1 734
    Par défaut
    Combien de lignes de la table histo vérifient la condition "DATE IT" BETWEEN '01/05/2007' AND '31/05/2007' AND "BASE_GPC"='1G' ?

    Combien de lignes de la table etl vérifient la condition "BASE_GPC"='1G' ?

    Combien de temps prend juste la requête suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM histo WHERE "DATE IT" BETWEEN '01/05/2007' AND '31/05/2007' AND "BASE_GPC"='1G'
    La théorie, c'est quand on sait tout mais que rien ne fonctionne.
    La pratique, c'est quand tout fonctionne mais que personne ne sait pourquoi.
    Ici, nous avons réuni théorie et pratique : Rien ne fonctionne ... et personne ne sait pourquoi !

    Réplication de base avec Postgresql : http://scheu.developpez.com/tutoriel.../log-shipping/

  9. #9
    Membre régulier
    Inscrit en
    Mai 2007
    Messages
    149
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 149
    Points : 89
    Points
    89
    Par défaut
    Je réponds rapidement en citant :
    Citation Envoyé par scheu Voir le message
    Combien de lignes de la table histo vérifient la condition "DATE IT" BETWEEN '01/05/2007' AND '31/05/2007' AND "BASE_GPC"='1G' ?
    10 500 lignes

    Combien de lignes de la table etl vérifient la condition "BASE_GPC"='1G' ?
    116 lignes

    Combien de temps prend juste la requête suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM histo WHERE "DATE IT" BETWEEN '01/05/2007' AND '31/05/2007' AND "BASE_GPC"='1G'
    99 secondes

  10. #10
    Membre expérimenté Avatar de scheu
    Inscrit en
    Juin 2007
    Messages
    1 506
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 1 506
    Points : 1 734
    Points
    1 734
    Par défaut
    Le problème vient donc juste du filtre WHERE "DATE IT" BETWEEN '01/05/2007' AND '31/05/2007' AND "BASE_GPC"='1G' sur la table histo, vu que ça prend la totalité du temps de la requête
    Quels sont les types de données des colonnes date_it et base_gpc ?
    Combien de temps met la requête SELECT * from histo ?
    Indique le résultat de "explain SELECT * from histo"

    As-tu configuré le fichier postgresql.conf ou bien as-tu tout laissé par défaut à l'installation ? Dans le fichier postgresql.conf, quelles sont les valeurs des paramètres shared_buffers, work_mem, temp_buffers, maintenance_work_mem ?

    Combien de RAM as-tu sur ton serveur ?
    La théorie, c'est quand on sait tout mais que rien ne fonctionne.
    La pratique, c'est quand tout fonctionne mais que personne ne sait pourquoi.
    Ici, nous avons réuni théorie et pratique : Rien ne fonctionne ... et personne ne sait pourquoi !

    Réplication de base avec Postgresql : http://scheu.developpez.com/tutoriel.../log-shipping/

  11. #11
    Membre régulier
    Inscrit en
    Mai 2007
    Messages
    149
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 149
    Points : 89
    Points
    89
    Par défaut
    Citation Envoyé par scheu Voir le message
    Le problème vient donc juste du filtre WHERE "DATE IT" BETWEEN '01/05/2007' AND '31/05/2007' AND "BASE_GPC"='1G' sur la table histo, vu que ça prend la totalité du temps de la requête
    Quels sont les types de données des colonnes date_it et base_gpc ?
    date it : date
    base gpc :character varying
    Combien de temps met la requête SELECT * from histo ?
    258 secondes soit 4,3 minutes
    Indique le résultat de "explain SELECT * from histo"
    "Seq Scan on histo (cost=0.00..56493.68 rows=374268 width=2180)"
    As-tu configuré le fichier postgresql.conf ou bien as-tu tout laissé par défaut à l'installation ?
    Tout est par défaut.
    Dans le fichier postgresql.conf, quelles sont les valeurs des paramètres shared_buffers, work_mem, temp_buffers, maintenance_work_mem ?
    shared_buffers = 32MB
    #work_mem = 1MB (J'ai laissé le # car c'est commenté je suppose)
    #temp_buffers = 8MB
    #maintenance_work_mem = 16MB

    Combien de RAM as-tu sur ton serveur ?
    Ce n'est pas un serveur, pour le moment tout est sur ma machine de développement qui possède 1Go de ram. Par la même occasion si tu as une préconisation pour le choix du serveur, je t'en prie.
    (Désolé j'ai pas répondu hier).

  12. #12
    Membre expérimenté Avatar de scheu
    Inscrit en
    Juin 2007
    Messages
    1 506
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 1 506
    Points : 1 734
    Points
    1 734
    Par défaut
    4 minutes pour parcourir une table de 300 000 lignes ça paraît beaucoup quand-même.
    Le problème doit venir soit de ton paramétrage postgresql, soit du hardware

    Si y a pas grand chose d'autre qui tourne sur ton pc, essaie d'augmenter le shared_buffers à 256MB, et le work_mem à 32MB, de reloader la conf (pg_ctl reload -D <rep>), et de retester

    Sinon c'est sans doute ton disque qui est lent, en tous les cas ce n'est pas un problème lié à ta requête
    La théorie, c'est quand on sait tout mais que rien ne fonctionne.
    La pratique, c'est quand tout fonctionne mais que personne ne sait pourquoi.
    Ici, nous avons réuni théorie et pratique : Rien ne fonctionne ... et personne ne sait pourquoi !

    Réplication de base avec Postgresql : http://scheu.developpez.com/tutoriel.../log-shipping/

  13. #13
    Membre régulier
    Inscrit en
    Mai 2007
    Messages
    149
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 149
    Points : 89
    Points
    89
    Par défaut
    Ok merci.
    Je ferai la configuration postgres sur le serveur quand je déploierai.

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

Discussions similaires

  1. importer des données excel dans une application delphi
    Par dino35 dans le forum Bases de données
    Réponses: 5
    Dernier message: 21/02/2011, 16h54
  2. Réponses: 2
    Dernier message: 18/09/2008, 08h20
  3. Réponses: 12
    Dernier message: 24/10/2007, 12h00
  4. [SQLserver2000] Lire un fichier pour importer des données
    Par cladsam dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 01/10/2007, 10h40
  5. Réponses: 4
    Dernier message: 04/05/2007, 12h58

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