PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 Général » Base de 30+Go: Alternatives à pg_dump/_pg_restore » 31/10/2012 17:39:55

Merwin
Réponses : 1

Bonjour,

Nous avons une base de donnée qui grossit, vite. Malheureusement, le projet est en développement constant, et régulièrement on dump la base de production, que l'on restore sur nos postes locaux pour tester les derniers développements, les mises à jour, etc à partir de la base de production. Ce processus prend de plus en plus de temps lorsque l'on restore la base. Comment éviter cela ?

Je ne sais pas s'il existe un moyen de faire une sorte de "restauration incrémentale" pour éviter de restaurer toute la base ? J'imagine que lorsque l'on a des bases de plusieurs Teras, on a ne plus se permettre ce genre de restauration. Quelles sont les alternatives avec PostgreSQL?

Merci d'avance,

#3 Re : Général » Comment optimiser cette requête » 01/10/2012 17:45:30

Bah c'est ce que je fais, je ne comprends pas. EXPLAIN ANALYZE (ma requete de 5s). Le ANALYZE prend 500ms et la requête ~5s...

#4 Re : Général » Comment optimiser cette requête » 01/10/2012 16:19:48

Bien sur, voici l'explain analyze :

"Hash Left Join  (cost=23123.80..52130.63 rows=252518 width=64) (actual time=198.798..529.180 rows=284502 loops=1)"
"  Hash Cond: (quittance_detail.contrat_sante_beneficiaire_id = benef.id)"
"  ->  Hash Join  (cost=10222.08..29810.31 rows=252518 width=50) (actual time=105.611..302.826 rows=284502 loops=1)"
"        Hash Cond: (quittance_detail.quittance_id = quittance.id)"
"        ->  Seq Scan on oa_quittance_detail quittance_detail  (cost=0.00..9202.33 rows=286233 width=50) (actual time=0.045..80.117 rows=284502 loops=1)"
"        ->  Hash  (cost=9712.24..9712.24 rows=31027 width=8) (actual time=105.502..105.502 rows=33715 loops=1)"
"              Buckets: 4096  Batches: 2  Memory Usage: 665kB"
"              ->  Hash Join  (cost=3398.36..9712.24 rows=31027 width=8) (actual time=30.081..100.203 rows=33715 loops=1)"
"                    Hash Cond: (dcd.debit_credit_client_id = dcc.id)"
"                    ->  Hash Join  (cost=1477.33..6808.16 rows=35170 width=8) (actual time=10.840..64.173 rows=33715 loops=1)"
"                          Hash Cond: (dcd.id = quittance.debit_credit_detail_id)"
"                          ->  Seq Scan on oa_debit_credit_detail dcd  (cost=0.00..3121.79 rows=112179 width=8) (actual time=0.011..20.195 rows=110691 loops=1)"
"                          ->  Hash  (cost=899.70..899.70 rows=35170 width=8) (actual time=10.694..10.694 rows=33715 loops=1)"
"                                Buckets: 4096  Batches: 2  Memory Usage: 659kB"
"                                ->  Seq Scan on oa_quittance quittance  (cost=0.00..899.70 rows=35170 width=8) (actual time=0.003..5.693 rows=33715 loops=1)"
"                    ->  Hash  (cost=1363.84..1363.84 rows=33936 width=4) (actual time=19.207..19.207 rows=33715 loops=1)"
"                          Buckets: 4096  Batches: 2  Memory Usage: 597kB"
"                          ->  Seq Scan on oa_debit_credit_client dcc  (cost=0.00..1363.84 rows=33936 width=4) (actual time=0.014..13.099 rows=33715 loops=1)"
"                                Filter: ((name_client)::text = 'prime'::text)"
"                                Rows Removed by Filter: 4581"
"  ->  Hash  (cost=12335.35..12335.35 rows=30830 width=22) (actual time=93.097..93.097 rows=30651 loops=1)"
"        Buckets: 2048  Batches: 2  Memory Usage: 824kB"
"        ->  Hash Left Join  (cost=9346.37..12335.35 rows=30830 width=22) (actual time=55.220..87.226 rows=30651 loops=1)"
"              Hash Cond: (benef.beneficiaire_partner_id = benef_partner.id)"
"              ->  Seq Scan on oa_contrat_sante_beneficiaire benef  (cost=0.00..1276.30 rows=30830 width=8) (actual time=0.020..7.226 rows=30651 loops=1)"
"              ->  Hash  (cost=6913.61..6913.61 rows=132461 width=22) (actual time=55.118..55.118 rows=132461 loops=1)"
"                    Buckets: 2048  Batches: 8  Memory Usage: 919kB"
"                    ->  Seq Scan on res_partner benef_partner  (cost=0.00..6913.61 rows=132461 width=22) (actual time=0.008..30.643 rows=132461 loops=1)"
"Total runtime: 537.357 ms"

Pour les tables, les seules clés primaires sont les champs "id".
Pour les index on les voit dans le explain non ?

#5 Re : Général » Afficher le contenu d'une table » 01/10/2012 14:56:52

Je suppose que ce n'est pas forcément une bonne chose, mais un simple 'ORDER BY id DESC' ne suffit t'il pas pour les petites tables ?

#6 Général » Comment optimiser cette requête » 01/10/2012 14:54:39

Merwin
Réponses : 6

Bonjour à tous,

J'éxécute la requête suivante, qui me renvoi ~280 000 lignes en 5s. C'est trop long pour le besoin, donc je cherche un moyen d'obtenir un meilleur temps de réponse. Je vous joint un screenshot du Explain de PgAdmin, ainsi que la requête et la sortie du explain en texte. Je ne comprends pas très bien la sortie du explain, donc si vous pouviez me donner quelques conseils, ce serait génial. Merci d'avance.

Je suis PostgreSQL 9.1/9.2.

Requête :

SELECT dcc.id "DCC", produit_ligne_name AS "Produit", benef_partner.name AS "Bénéficiaire",
       commission_ttc_prix "Commission", vente_ht_prix "Vente Prix HT",
       vente_tx_prix "Vente Taxe", vente_ttc_prix "Vente Prix TTC", 0.0 "Frais de gestion HT",
       0.0 "Frais de gestion TTC", 0.0 "Commission Apporteur", 0.0 "Geste Com HT", 0.0 "Geste Com Taxe",
       0.0 "Geste Com TTC"
FROM       oa_quittance_detail quittance_detail
LEFT JOIN  oa_contrat_sante_beneficiaire benef ON quittance_detail.contrat_sante_beneficiaire_id = benef.id
LEFT JOIN  res_partner benef_partner ON benef.beneficiaire_partner_id = benef_partner.id
INNER JOIN oa_quittance quittance ON quittance_detail.quittance_id = quittance.id
INNER JOIN oa_debit_credit_detail dcd ON quittance.debit_credit_detail_id = dcd.id
INNER JOIN oa_debit_credit_client dcc ON dcd.debit_credit_client_id = dcc.id

Explain:

"Hash Left Join  (cost=23273.45..53868.33 rows=286233 width=67)"
"  Hash Cond: (quittance_detail.contrat_sante_beneficiaire_id = benef.id)"
"  ->  Hash Join  (cost=10371.73..30313.14 rows=286233 width=53)"
"        Hash Cond: (quittance_detail.quittance_id = quittance.id)"
"        ->  Seq Scan on oa_quittance_detail quittance_detail  (cost=0.00..9202.33 rows=286233 width=53)"
"        ->  Hash  (cost=9794.10..9794.10 rows=35170 width=8)"
"              ->  Hash Join  (cost=3376.83..9794.10 rows=35170 width=8)"
"                    Hash Cond: (dcd.debit_credit_client_id = dcc.id)"
"                    ->  Hash Join  (cost=1477.33..6808.16 rows=35170 width=8)"
"                          Hash Cond: (dcd.id = quittance.debit_credit_detail_id)"
"                          ->  Seq Scan on oa_debit_credit_detail dcd  (cost=0.00..3121.79 rows=112179 width=8)"
"                          ->  Hash  (cost=899.70..899.70 rows=35170 width=8)"
"                                ->  Seq Scan on oa_quittance quittance  (cost=0.00..899.70 rows=35170 width=8)"
"                    ->  Hash  (cost=1267.67..1267.67 rows=38467 width=4)"
"                          ->  Seq Scan on oa_debit_credit_client dcc  (cost=0.00..1267.67 rows=38467 width=4)"
"  ->  Hash  (cost=12335.35..12335.35 rows=30830 width=22)"
"        ->  Hash Left Join  (cost=9346.37..12335.35 rows=30830 width=22)"
"              Hash Cond: (benef.beneficiaire_partner_id = benef_partner.id)"
"              ->  Seq Scan on oa_contrat_sante_beneficiaire benef  (cost=0.00..1276.30 rows=30830 width=8)"
"              ->  Hash  (cost=6913.61..6913.61 rows=132461 width=22)"
"                    ->  Seq Scan on res_partner benef_partner  (cost=0.00..6913.61 rows=132461 width=22)"

Screenshot PgAdmin 3 :

697830PgAdminReq1.png

#7 Re : Général » Requête : copie de donnée hiérarchique » 29/03/2012 14:02:37

Je n'ai jamais utilisé WITH, ça a l'air pratique, je reviens vers vous si je ne m'en sort pas !

Merci pour l'aide :-)

#8 Re : Général » Requête : copie de donnée hiérarchique » 29/03/2012 12:24:20

Par exemple dans la table 1, j'ai un partent_id = 1 pour la ligne 2.
Lorsque je vais copier cette ligne dans ma table 2, elle aura un parent_id égal à 80. Soit l'équivalent dans la table 2 du parent de la ligne 2 dans la table 1.
Ici, parent_id étant, dans chacun des tables, une foreignkey vers elle même.

Aujourd'hui je le fais par le code :

nouvel_id_ligne_1_table_2 = INSERT INTO table2 ....
nouvel_id_ligne_2_table_2 = INSERT INTO table2 .... parent_id = nouvel_id_ligne_1_table_2

Mais ça revient à faire 80 INSERT, d'affilé, puisqu'a chaque fois j'ai besoin de l'ID d'un enregistrement précédent pour le définir comme parent de mon nouvel enregistrement.
C'est très lourd :-/

#9 Re : Général » Requête : copie de donnée hiérarchique » 29/03/2012 10:15:57

Malheureusement, je ne suis pas responsable du schéma et je dois faire avec :-(
Je pense qu'a l'origine le problème venait d'OpenERP et de son ORM (plus que médiocre à mon sens).

La consigne étant d'utilisé un maximum l'ORM, la modélisation a été influencée par les possibilités de ORM,
notamment dans ce cas précis l'utilisation de 'child_of' qui permet de tester la parenté via l'ORM, mais qui du coup nécéssite
un champ parent_id dans la table en question...

D'ou ma problématique :-(

#10 Général » Requête : copie de donnée hiérarchique » 29/03/2012 09:41:37

Merwin
Réponses : 7

Bonjour à tous,

Je vous expose mon problème :

J'ai une table, appellons la produits, qui contient des lignes décrivant une arborescence de produits :

id  +   parent_id   +   name
----------------------------
1   |               |   Produit #1
2   |           1   |   Produit #2
3   |           2   |   Produit #3

J'ai une table comme ça qui contient environ 100 lignes.
Ensuite, j'ai une seconde table, que l'on appellera produits_souscrits.

La table est identique, avec deux champ en plus : souscrit et client_id :

id  +   parent_id   +   souscrit  + client_id + ... d'autres colonnes comme 'produit_id' qui référence la première table
-------------------------------------------------------------
80   |              |          t  | 150
81   |         80   |          t  | 150
82   |         81   |          f  | 150

L'idée étant simple, quand je souscrit un contrat pour un client, je vais chercher dans ma première tables
les lignes qu'il peut souscrire. Puis je les copies dans ma seconde table.

Il faut lors de la copie "reconstuire" la notion de parent_id, puisque dans la seconde table, les ids sont différents de la première.
Comment faire, sachant qu'ici je cherche la performance ? (Actuellement je fais un tri via du code, puis je fais 80 INSERT dans la nouvelle table).

Merci d'avance,

Pied de page des forums

Propulsé par FluxBB