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 Re : Général » SELECT *, ORDER BY et CLUSTER » 09/02/2012 15:35:38

Effectivement je n'avais pas fait d'ANALYZE après le CLUSTER.
Je pensais qu'il n'y en avait pas besoin, Désolé.
Maintenant cela semble beaucoup mieux...

Voici le résultat :

schemaname |        tablename         | attname | null_frac | avg_width | n_distinct |                                       most_common_vals                                       |                                         most_common_freqs                                         |                                             histogram_bounds                                              | correlation
------------+--------------------------+---------+-----------+-----------+------------+----------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------+-------------
public     |  A  | C1 |         0 |         4 |      98419 | {18331342,122919545,166293478,336171882,8235717,9989273,12796743,14820287,46257437,54247373} | {0.001,0.001,0.001,0.001,0.000666667,0.000666667,0.000666667,0.000666667,0.000666667,0.000666667} | {52191,29147811,70914521,110918314,152345409,198650891,249337412,300888640,335856464,387211576,459899680} |           1
(1 ligne)



explain analyze select * from A ORDER BY C1;
                                                                          QUERY PLAN                                                                           
---------------------------------------------------------------------------------------------------------------------------------------------------------------
Index Scan using C1 on A (cost=0.00..20447583.96 rows=672784128 width=8) (actual time=82.764..251109.888 rows=672784026 loops=1)
Total runtime: 312674.035 ms
(2 lignes)

merci pour votre aide,

Je ne connaissais pas l'usage de pg_stats de cette manière

Merci encore

#2 Re : Général » SELECT *, ORDER BY et CLUSTER » 09/02/2012 13:26:50

La structure complete de la table et de l'index est:

CREATE TABLE A (   C1 integer,   C2 integer ) ;
CREATE INDEX id_C1  ON A   USING btree    (C1);

Voici le résultat de la requete
SELECT * from pg_stats where attname = 'C1' and tablename = 'A';

schemaname |        tablename         | attname | null_frac | avg_width | n_distinct  |   most_common_vals    |     most_common_freqs     |                                              histogram_bounds                                              | correlation
------------+--------------------------+---------+-----------+-----------+-------------+-----------------------+---------------------------+------------------------------------------------------------------------------------------------------------+-------------
public     | A | C1 |         0 |         4 | 2.24102e+06 | {260776233,321886708} | {0.000666667,0.000666667} | {317430,29140989,72490852,111639837,162726571,217745980,264734876,305660178,336754552,385767595,458987002} |   0.0102128
(1 ligne)


J'ai refait un explain analyze :
set enable_seqscan to on;
explain analyze select * from t_mes_hom_ss_doublon_res ORDER BY mes_id1;
                                                                     QUERY PLAN                                                                     
----------------------------------------------------------------------------------------------------------------------------------------------------
Sort  (cost=163542949.23..165224909.23 rows=672784000 width=8) (actual time=843426.850..1023723.740 rows=672784026 loops=1)
   Sort Key: C1
   Sort Method:  external merge  Disk: 15783792kB
   ->  Seq Scan on A  (cost=0.00..9704761.00 rows=672784000 width=8) (actual time=13.487..146788.687 rows=672784026 loops=1)
Total runtime: 1084920.213 ms
(5 lignes)


set enable_seqscan to off;
explain analyze select * from t_mes_hom_ss_doublon_res ORDER BY mes_id1;
                                                                          QUERY PLAN                                                                         
--------------------------------------------------------------------------------------------------------------------------------------------------------------
Sort  (cost=263542949.23..265224909.23 rows=672784000 width=8) (actual time=840698.987..1017110.236 rows=672784026 loops=1)
   Sort Key: C1
   Sort Method:  external merge  Disk: 15783792kB
   ->  Seq Scan on A  (cost=100000000.00..109704761.00 rows=672784000 width=8) (actual time=15.570..143822.771 rows=672784026 loops=1)
Total runtime: 1077951.970 ms

#3 Re : Général » SELECT *, ORDER BY et CLUSTER » 09/02/2012 10:48:37

merci pour votre réponse rapide
j'ai un posgres version 8.3
seq_page_cost = 1.0 (valeur par defaut)
random_page_cost = 4.0    (valeur par defaut)

Concernant la table, je ne fais pas d'update ni d'insert dessus. elle est en "Lecture Seule"

Sinon voici les valeurs :

set enable_seqscan to off;
explain select * from A ORDER BY C1;
QUERY PLAN                                             
------------------------------------------------------------------------------------------------------
Sort  (cost=263542949.23..265224909.23 rows=672784000 width=8)
   Sort Key: C1
   ->  Seq Scan on A  (cost=100000000.00..109704761.00 rows=672784000 width=8)


set enable_seqscan to on;
explain select * from A ORDER BY C1;
                                         QUERY PLAN                                         
--------------------------------------------------------------------------------------------
Sort  (cost=163542949.23..165224909.23 rows=672784000 width=8)
   Sort Key: C1
   ->  Seq Scan on A  (cost=0.00..9704761.00 rows=672784000 width=8)
(3 lignes)

#4 Général » SELECT *, ORDER BY et CLUSTER » 09/02/2012 10:34:37

Ours77
Réponses : 7

Bonjour,

J'ai un table A qui contient 2 colonne d'entier C1 et C2.
J'ai un index id_C1 qui est un index sur la première colonne.
Puis j'ai fait un CLUSTER de A avec cet index.

Je veux parcourir toute ma table (près de 700 millions d’éléments...) en utilisant l'index c1.

Si je fait :

Select * from A order by C1.

Le plan de requête n'utilise pas l'index  et le temps de réponse est très très long  (trop pour mon application....).

QUERY PLAN                                         
--------------------------------------------------------------------------------------------
Sort  (cost=163542949.23..165224909.23 rows=672784000 width=8)
   Sort Key:C1
   ->  Seq Scan onA  (cost=0.00..9704761.00 rows=672784000 width=8)
(3 lignes)

Si je fait un "Select * from A" est ce que je suis assuré de récupérer les données selon C1 vu que j'ai fait un CLUSTER sur ma table selon cette colonne ?

Existe t il une requete du genre
"Select * from A using index  id_C1

Merci d'avance pour votre aide

#5 Re : Général » Recuperation de lignes non bloquées sur une table » 27/10/2011 08:59:43

Merci pour la requête.
Je ne savais pas qu'un Update pouvait renvoyer des valeurs

#6 Re : Général » Recuperation de lignes non bloquées sur une table » 26/10/2011 14:29:16

Effectivement plutot que

Begin;
"select * from table limit 1 for update;" Le limit 1 n'est la que pour recupere une ligne a traiter
Mon processus;
"update ..." de la ligne;
End;

Cela deviendra

select id from table where a_traiter=true limit 1; 
update table set a_traiter=false where id=10;
Begin;
Mon processus;
"update ..." de la ligne;
End;

#7 Re : Général » Recuperation de lignes non bloquées sur une table » 26/10/2011 14:14:36

Je pense que je vais m'orienter vers votre solution (celle de dverite) parce que naviguer dans les tables "systemes" pour voir ce qui se passe ne me parait pas très "sain" pour un fonction normale.
Ce qui m'étonne c'est que trouver les lignes qui ne sont pas bloquées sur une table ne soient pas gérer "en natif" par PostgreSQL.
Tout les systemes qui font du traitement en paralleles de données doivent avoir ce pb non? Ou chacun le résout avec sa propre méthode?

#8 Re : Général » Recuperation de lignes non bloquées sur une table » 26/10/2011 10:44:38

Le pb avec la table pg_locks c'est que je ne voit que la transaction qui bloque :
"<IDLE> in transaction" dans la colonne current_query. Je ne vois pas la requete a l'interieur de la transaction (ou alors je ne sais pas comment faire....)
Comment je peux recupere le numero de la ligne qui est bloqué ?

#9 Général » Recuperation de lignes non bloquées sur une table » 26/10/2011 10:06:36

Ours77
Réponses : 11

Bonjour,
J'ai une table qui contient des millions d’éléments.

J'ai des processus a lancer dessus qui bloque certaines lignes avec la requete
select * from table for update;
qui est elle meme encapsuler dans une transaction;

Exemple:

Begin;
"select * from table limit 1 for update;" Le limit 1 n'est la que pour recupere une ligne a traiter
Mon processus;
"update ..." de la ligne;
End;

Je souhaiterai lancer un nouveau processus qui recupererai la première ligne non bloquée  avec une requête du genre 

select * from table where ligne_pas_bloque"

Si j'utilise la requete  A   "select * from table for share;"
la requete "select * from table"
me renvoi aussi les lignes qui sont prise dans la requete A
Si j'utilise la requete B  "select * from table for update;"
la requete  " select * from table"
ne me renvoi rien tant que B n'est pas terminé ce qui n'est pas optimale pour paralléliser les traitements sur ma table...

J'ai deja essayer de regarder la table pg_locks pour savoir quelle(s) ligne(s) sur la table était(ent) verrouillée(s) mais je ne suis pas sur que cela soit la bonne stratégie...

Pourriez vous m'indiquez comment effectuer une telle requête  soit une stratégie plus appropriée ?

Merci beaucoup

Pied de page des forums

Propulsé par FluxBB