Par Psycho le 01/11/2007 - 00:30
Bonjour,
Je créé actuellement un système représentant les cases d'un monde. Selon nos calculs, la table devrait contenir plus de 25.000.000 de records au départ (pour quelques 4 GO) et grandir petit à petit.
Après avoir regarder le forum, j'ai vu que la solution du partionnement semblait être une bonne chose à faire.
J'ai donc découper ma carte en 25 tables différents (plus facile, carte 5000 x 5000 découpé en 25 zone de 1000 x 1000, en gros, 1.000.000 de record par table).
J'ai voulu faire un peu des tests sur ca, j'ai donc remplit mes tables avec les deux façon différente.
Une solution avec partitionnement et une sans.
1) Première constatation, le replissage de la partie avec partitionnement m'as pris... beaucoup beaucoup plus de temps (12h contre 4h environ).
A la rigueur, le problème ne me gène pas plus que ca car les tables seront accédé principalement par SELECT.
2) Ensuite j'ai fais mes test de SELECT sur les table... et fort malheureusement, le SELECT sur les tables partitionnés prend plus de temps aussi dans la plupart des cas.
J'ai essayer de faire un EXPLAIN, et il semble que la clause constraint_exception ne soit pas pris en compte (j'ai mis ON dans le fichier postgres.conf et j'ai même vérifier en faisant SET constraint_exception = on avant ma requête).
Je suppose que si j'arrive à ce qu'il prenne en compte ce paramètre, ma solution avec partitionnement sera meilleur, mais pour l'instant... non.
(au passage, si vous avez des conseils de configuration pour ce genre de donnée, taille des buffers et autre, j'avoue ne pas m'y connaître encore beaucoup là dedans, je monte en compétence doucement...)
Les test fait, avec deux requêtes :
EXPLAIN ANALYZE SELECT *
FROM monde
WHERE x BETWEEN -1600 AND -1400
AND y BETWEEN 400 AND 600;
(cette requête va obliger le système avec partitionnement à aller chercher dans deux tables différentes)
Sans partitionnement :
1ère exécution : Total runtime: 40537.848 ms
2ième exécution : Total runtime: 191.484 ms
Avec partitionnement :
1ère exécution : Total runtime: 32166.446 ms
2ième exécution : Total runtime: 230.970 ms
EXPLAIN ANALYZE SELECT * FROM monde_test
WHERE x BETWEEN -1800 AND -1600
AND y BETWEEN -200 AND 0;
(la rechercher sera uniquement dans une seul table)
Sans partitionnement :
1ère exécution : Total runtime : 40735.029 ms (un petit peu moins en fait, j'ai pris le mauvais chiffre)
2ième exécution : Total runtime: 192.634 ms
Avec partitionnement :
1ère exécution : Total runtime: 32196.732 ms
2ième exécution : Total runtime: 216.911 ms
Le EXPLAIN ANALYZE (pour la première requete)
Sans partitionnement :
QUERY PLAN
Bitmap Heap Scan on monde_test (cost=37841.43..131175.92 rows=40494 width=18) (actual time=173.803..186.790 rows=40401 loops=1)
Recheck Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Bitmap Index Scan on monde_test_pkey (cost=0.00..37831.30 rows=40494 width=0) (actual time=173.659..173.659 rows=40401 loops=1)
Index Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
Total runtime: 191.484 ms
Avec partitionnement :
QUERY PLAN
Result (cost=0.00..78658.27 rows=35415 width=18) (actual time=0.212..224.933 rows=40401 loops=1)
-> Append (cost=0.00..78658.27 rows=35415 width=18) (actual time=0.210..205.276 rows=40401 loops=1)
-> Index Scan using monde_pkey on monde (cost=0.00..36677.99 rows=15754 width=18) (actual time=0.210..59.137 rows=20100 loops=1)
Index Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Index Scan using monde_m2p2_pkey on monde_m2p2 monde (cost=0.00..3388.55 rows=1 width=18) (actual time=16.332..16.332 rows=0 loops=1)
Index Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Index Scan using monde_m1p2_pkey on monde_m1p2 monde (cost=0.00..3217.28 rows=1 width=18) (actual time=17.147..17.147 rows=0 loops=1)
Index Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Index Scan using monde_c0p2_pkey on monde_c0p2 monde (cost=0.00..8.46 rows=1 width=18) (actual time=0.083..0.083 rows=0 loops=1)
Index Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Index Scan using monde_p1p2_pkey on monde_p1p2 monde (cost=0.00..8.46 rows=1 width=18) (actual time=0.062..0.062 rows=0 loops=1)
Index Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Index Scan using monde_p2p2_pkey on monde_p2p2 monde (cost=0.00..8.46 rows=1 width=18) (actual time=0.060..0.060 rows=0 loops=1)
Index Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Index Scan using monde_m2p1_pkey on monde_m2p1 monde (cost=0.00..8.38 rows=1 width=18) (actual time=0.019..0.019 rows=0 loops=1)
Index Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Index Scan using monde_m1p1_pkey on monde_m1p1 monde (cost=0.00..8.38 rows=1 width=18) (actual time=0.018..0.018 rows=0 loops=1)
Index Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Bitmap Heap Scan on monde_c0p1 monde (cost=171.52..267.32 rows=25 width=18) (actual time=0.099..0.099 rows=0 loops=1)
Recheck Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Bitmap Index Scan on monde_c0p1_pkey (cost=0.00..171.51 rows=25 width=0) (actual time=0.097..0.097 rows=0 loops=1)
Index Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Index Scan using monde_p1p1_pkey on monde_p1p1 monde (cost=0.00..8.38 rows=1 width=18) (actual time=0.019..0.019 rows=0 loops=1)
Index Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Index Scan using monde_p2p1_pkey on monde_p2p1 monde (cost=0.00..8.38 rows=1 width=18) (actual time=0.018..0.018 rows=0 loops=1)
Index Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Bitmap Heap Scan on monde_m2c0 monde (cost=2858.69..9744.68 rows=8989 width=18) (actual time=15.991..19.954 rows=10100 loops=1)
Recheck Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Bitmap Index Scan on monde_m2c0_pkey (cost=0.00..2856.44 rows=8989 width=0) (actual time=15.909..15.909 rows=10100 loops=1)
Index Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Bitmap Heap Scan on monde_m1c0 monde (cost=3385.20..10203.41 rows=10625 width=18) (actual time=16.620..20.841 rows=10201 loops=1)
Recheck Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Bitmap Index Scan on monde_m1c0_pkey (cost=0.00..3382.55 rows=10625 width=0) (actual time=16.566..16.566 rows=10201 loops=1)
Index Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Index Scan using monde_c0c0_pkey on monde_c0c0 monde (cost=0.00..8.46 rows=1 width=18) (actual time=0.075..0.075 rows=0 loops=1)
Index Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Index Scan using monde_p1c0_pkey on monde_p1c0 monde (cost=0.00..8.46 rows=1 width=18) (actual time=0.062..0.062 rows=0 loops=1)
Index Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Index Scan using monde_p2c0_pkey on monde_p2c0 monde (cost=0.00..8.46 rows=1 width=18) (actual time=0.062..0.062 rows=0 loops=1)
Index Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Index Scan using monde_m2m1_pkey on monde_m2m1 monde (cost=0.00..3423.90 rows=1 width=18) (actual time=15.608..15.608 rows=0 loops=1)
Index Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Index Scan using monde_m1m1_pkey on monde_m1m1 monde (cost=0.00..3670.22 rows=1 width=18) (actual time=14.538..14.538 rows=0 loops=1)
Index Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Index Scan using monde_c0m1_pkey on monde_c0m1 monde (cost=0.00..8.46 rows=1 width=18) (actual time=0.076..0.076 rows=0 loops=1)
Index Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Index Scan using monde_p1m1_pkey on monde_p1m1 monde (cost=0.00..8.46 rows=1 width=18) (actual time=0.061..0.061 rows=0 loops=1)
Index Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Index Scan using monde_p2m1_pkey on monde_p2m1 monde (cost=0.00..8.46 rows=1 width=18) (actual time=0.060..0.060 rows=0 loops=1)
Index Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Index Scan using monde_m2m2_pkey on monde_m2m2 monde (cost=0.00..3309.03 rows=1 width=18) (actual time=15.785..15.785 rows=0 loops=1)
Index Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Index Scan using monde_m1m2_pkey on monde_m1m2 monde (cost=0.00..4620.84 rows=1 width=18) (actual time=16.625..16.625 rows=0 loops=1)
Index Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Index Scan using monde_c0m2_pkey on monde_c0m2 monde (cost=0.00..8.50 rows=1 width=18) (actual time=0.100..0.100 rows=0 loops=1)
Index Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Index Scan using monde_p1m2_pkey on monde_p1m2 monde (cost=0.00..8.50 rows=1 width=18) (actual time=0.074..0.074 rows=0 loops=1)
Index Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))
-> Index Scan using monde_p2m2_pkey on monde_p2m2 monde (cost=0.00..8.38 rows=1 width=18) (actual time=0.023..0.023 rows=0 loops=1)
Index Cond: ((x >= -1600) AND (x <= -1400) AND (y >= 400) AND (y <= 600))