Comparatif SIG, match retour - 2 - résultats détaillés
lun. 28 mai 2018 (PostgreSQL)Cet article est une partie de l'article Comparatif SIG, match retour :
Résultats détaillés
Recherche des données spatiales non valides avec explications détaillées (Q1)
En avril 2017, cette première requête tournait 9 fois plus rapidement sous SQL Server que PostgreSQL.
Requête SQL Server :
SELECT *, GEOM.IsValidDetailed()
FROM S_ADR.CODE_INSEE_CODE_POSTAL
WHERE GEOM.STIsValid() = 0
Requête PostgreSQL :
SELECT *, ST_IsValidDetail(geom)
FROM s_adr.code_insee_code_postal
WHERE ST_IsValid(geom) = false
Durée (ms) | pour 1 client | pour 16 clients |
---|---|---|
SQL Server | 333 | 1 865 |
PostgreSQL | 435 | 2 668 |
Rapport PostgreSQL / SQL Server | 131 % | 143 % |
Avec cette nouvelle série de tests, l'écart de performance s'est considérablement réduit entre les deux moteurs. Pour les deux SGBDR, la recherche est retournée en moins d'une demi-seconde.
Cette différence ne varie pas lorsqu'on lance les requêtes jusqu'à 16 fois en simultané, chacune d'elle prenant autour de 2 secondes.
Comme pour les tests sur Windows, SQL Server est plus rapide que PostgreSQL. La différence de performance est toutefois ténu car uniquement 1,3 fois plus rapide.
Recherche de la plus grande commune en surface (Q2)
Lors du premier test, les deux SGBDR étaient coude-à-coude avec un très léger avantage en faveur de PostgreSQL.
Requête SQL Server :
SELECT *
FROM S_GEO.COMMUNE
WHERE GEOM.STArea() = (SELECT MAX(GEOM.STArea()) FROM S_GEO.COMMUNE)
Requête PostgreSQL :
SELECT *
FROM S_GEO.COMMUNE
WHERE ST_Area(geom) = (SELECT MAX(ST_Area(GEOM)) FROM S_GEO.COMMUNE)
Durée (ms) | pour 1 client | pour 16 clients |
---|---|---|
SQL Server | 412 | 6 350 |
PostgreSQL | 52 | 91 |
Rapport PostgreSQL / SQL Server | 13 % | 1,4 % |
Ce test montre que PostgreSQL est 8 fois plus rapide que SQL Server sur une requête. SQL Server met même 70 fois plus de temps lors du test en parallélisation.
Agrégation spatiale des communes en départements (Q3)
Il y a un an, ce test tournait 10 fois plus vite sous SQL Server.
Requête SQL Server :
SELECT CODE_DEPT, geometry::UnionAggregate(GEOM)
FROM [S_GEO].[COMMUNE]
GROUP BY CODE_DEPT
Requête PostgreSQL :
SELECT CODE_DEPT, ST_Union(GEOM)
FROM S_GEO.COMMUNE
GROUP BY CODE_DEPT
Durée (ms) | pour 1 client | pour 16 clients |
---|---|---|
SQL Server | 2 730 | 18 826 |
PostgreSQL | 12 824 | 44 958 |
Rapport PostgreSQL / SQL Server | 470 % | 239 % |
L'avantage est encore pour SQL Server, mais de façon moins marquée. Il est 5 fois plus rapide que PostgreSQL. Cependant lorsque 16 requêtes sont lancées en parallèle, l'écart se réduit à 2,5 fois.
Recherche des communes les plus proches de certains points (Q4)
En avril 2017, lors des premiers tests PostgreSQL mettait environ 2 fois moins de temps que SQL Server.
Requête SQL Server :
WITH
POINTS AS (
SELECT CAST('POINT(430354.933 6623007.700)' AS geometry) AS P,1 AS N
UNION ALL SELECT CAST('POINT(980190.133 6333111.233)' AS geometry),2
UNION ALL SELECT CAST('POINT(574865.267 6909297.167)' AS geometry),3
UNION ALL SELECT CAST('POINT(501587.200 6548318.933)' AS geometry),4
UNION ALL SELECT CAST('POINT(444282.067 6251421.667)' AS geometry),5
UNION ALL SELECT CAST('POINT(460953.333 6775817.633)' AS geometry),6
UNION ALL SELECT CAST('POINT(1032008.400 6323716.133)' AS geometry),7
UNION ALL SELECT CAST('POINT(875328.767 6866887.500)' AS geometry),8
UNION ALL SELECT CAST('POINT(666398.867 6560452.500)' AS geometry),9
UNION ALL SELECT CAST('POINT(354528.400 6636467.900)' AS geometry),10
UNION ALL SELECT CAST('POINT(1251250.400 6464646.125)' AS geometry),11
UNION ALL SELECT CAST('POINT(315060.950 6874532.888)' AS geometry),12
UNION ALL SELECT CAST('POINT(415263.920 7077070.707)' AS geometry),13
UNION ALL SELECT CAST('POINT(559988.123 6050300.400)' AS geometry),14
UNION ALL SELECT CAST('POINT(334455.250 6333111.200)' AS geometry),15
UNION ALL SELECT CAST('POINT(312459.258 7172737.333)' AS geometry),16
),
DISTANCES AS (
SELECT
N, P, [ID_GEOFLA], [INSEE_COM], [NOM_COM],
GEOM, P.STDistance(GEOM) AS D,
RANK() OVER(PARTITION BY N ORDER BY P.STDistance(GEOM)) AS R
FROM [S_GEO].[COMMUNE] CROSS JOIN POINTS
)
SELECT *,
CASE D WHEN 0 THEN 'intérieur' ELSE 'extérieur' END AS SITUATION
FROM DISTANCES WHERE R = 1
Requête PostgreSQL :
WITH POINTS AS (
SELECT CAST('POINT(430354.933 6623007.700)' AS geometry) AS P,1 AS N
UNION ALL SELECT CAST('POINT(980190.133 6333111.233)' AS geometry),2
UNION ALL SELECT CAST('POINT(574865.267 6909297.167)' AS geometry),3
UNION ALL SELECT CAST('POINT(501587.200 6548318.933)' AS geometry),4
UNION ALL SELECT CAST('POINT(444282.067 6251421.667)' AS geometry),5
UNION ALL SELECT CAST('POINT(460953.333 6775817.633)' AS geometry),6
UNION ALL SELECT CAST('POINT(1032008.400 6323716.133)' AS geometry),7
UNION ALL SELECT CAST('POINT(875328.767 6866887.500)' AS geometry),8
UNION ALL SELECT CAST('POINT(666398.867 6560452.500)' AS geometry),9
UNION ALL SELECT CAST('POINT(354528.400 6636467.900)' AS geometry),10
UNION ALL SELECT CAST('POINT(1251250.400 6464646.125)' AS geometry),11
UNION ALL SELECT CAST('POINT(315060.950 6874532.888)' AS geometry),12
UNION ALL SELECT CAST('POINT(415263.920 7077070.707)' AS geometry),13
UNION ALL SELECT CAST('POINT(559988.123 6050300.400)' AS geometry),14
UNION ALL SELECT CAST('POINT(334455.250 6333111.200)' AS geometry),15
UNION ALL SELECT CAST('POINT(312459.258 7172737.333)' AS geometry),16
),
DISTANCES AS (
SELECT
N, P, ID_GEOFLA, INSEE_COM, NOM_COM, GEOM,
ST_Distance(P, GEOM) AS D,
RANK() OVER(PARTITION BY N ORDER BY ST_Distance(P, GEOM)) AS R
FROM S_GEO.COMMUNE
CROSS JOIN POINTS
)
SELECT *,
CASE D WHEN 0 THEN 'intérieur' ELSE 'extérieur' END AS SITUATION
FROM DISTANCES WHERE R = 1
Tandis que pour les autres tests, PostgreSQL améliore ses performances sur SQL Server en parallélisant les appels, ici, les performances de PostgreSQL s'effondrent avec la montée en charge.
PostgreSQL met 21 fois plus de temps pour 16 requêtes concurrentes que pour une requête unique !
En étudiant le plan d'exécution de la requête sur PostgreSQL, nous avons remarqué une écriture massive de fichier temporaires pour effectuer le tri des données :
-> Sort (cost=387593.26..389025.18 rows=572768 width=1131)
(actual time=3978.145..4398.740 rows=572768 loops=1)
Sort Key: points.n, (st_distance(points.p, commune.geom))
Sort Method: external merge Disk: 641960kB
626 Mo de données temporaires écrites sur disque sont nécessaires lors de chaque requête pour trier 572 768 lignes.
On remarque également que sur ces 572 768 lignes, seules 16 sont conservées :
CTE Scan on distances (cost=434846.94..447741.38 rows=2864 width=324) (actual time=4339.336..8596.685 rows=16 loops=1)
Filter: (r = 1)
Rows Removed by Filter: 572752
L'objectif de la requête est ici de trouver pour chacun des 16 points, l'unique commune étant la plus proche de ce point.
Le mot clé LATERAL
permet d'effectuer exactement ce type de requête : pour chaque ligne d'un élément FROM fournissant les colonnes référencées, l'élément LATERAL est évalué en utilisant cette valeur de ligne. Les lignes résultantes sont jointes comme d'habitude aux lignes résultants du calcul. Ceci est répété pour chaque ligne provenant de la table source.
Nous avons optimisé la requête en utilisant la commande LATERAL
:
WITH points (p, n) AS (VALUES
(ST_MakePoint(430354.933, 6623007.700),1),
(ST_MakePoint(980190.133, 6333111.233),2),
(ST_MakePoint(574865.267, 6909297.167),3),
(ST_MakePoint(501587.200, 6548318.933),4),
(ST_MakePoint(444282.067, 6251421.667),5),
(ST_MakePoint(460953.333, 6775817.633),6),
(ST_MakePoint(1032008.400, 6323716.133),7),
(ST_MakePoint(875328.767, 6866887.500),8),
(ST_MakePoint(666398.867, 6560452.500),9),
(ST_MakePoint(354528.400, 6636467.900),10),
(ST_MakePoint(1251250.400, 6464646.125),11),
(ST_MakePoint(315060.950, 6874532.888),12),
(ST_MakePoint(415263.920, 7077070.707),13),
(ST_MakePoint(559988.123, 6050300.400),14),
(ST_MakePoint(334455.250, 6333111.200),15),
(ST_MakePoint(312459.258, 7172737.333),16)
)
SELECT
n, p, id_geofla, insee_com, nom_com, geom, d,
RANK() OVER(PARTITION BY n ORDER BY ST_Distance(p, geom)) AS r,
CASE d WHEN 0 THEN 'interieur' ELSE 'exterieur' END AS situation
FROM points,
LATERAL (
SELECT id_geofla, insee_com, nom_com, geom, ST_Distance(p, geom) AS d
FROM s_geo.commune
ORDER BY p <-> s_geo.commune.geom
LIMIT 1
) sub;
Par rapport au plan précédent, la requête actuel utilise l'index GiST commune_geom_idx
de la table commune
:
-> Index Scan using commune_geom_idx on commune
(cost=0.28..26101.61 rows=35798 width=1103)
(actual time=0.248..0.248 rows=1 loops=16)
Le temps d'exécution de la requête passe de 3 309 ms à 14 ms !
Le lancement de plusieurs dizaines voire centaines de requêtes en parallèle n'ont qu'un impact négligeable sur les performances. Pour 64 requêtes simultanées, les 8 processeurs tournent à 100% pendant quelques secondes et chaque requête prend en moyenne 23 ms.
Et que cela soit ensuite pour 256, et même 512 requêtes lancées en parallèle, le script donne un temps moyen entre 20 et 30 ms pour chaque requête.
Nous avons optimisé la requête SQL Server à l'aide de l'instruction CROSS APPLY pour obtenir le même type d'amélioration des perfomances. Son utilisation ne permettait cependant qu'une amélioration marginale de la requête.
Durée (ms) | pour 1 client | pour 16 clients |
---|---|---|
SQL Server | 1 498 | 20 401 |
PostgreSQL originale | 3 309 | 68 944 |
PostgreSQL optimisée | 14 | 21 |
Rapport PostgreSQL / SQL Server | 0,9 % | 0,1 % |
Le résultat avec la requête optimisée est sans appel avec PostgreSQL quasiment 1000 fois plus rapide que SQL Server pour 16 clients.
La capacité de montée en charge sur le test Q4 grâce à l'index GiST est la plus grosse surprise de cette nouvelle série de tests. Un article à lui tout seul mériterait que l'on s'attarde sur cette fonctionnalité remarquable de PostgreSQL.
Recherches de départements distants de moins de 5 km et ne se touchant pas (Q5)
Lors des précédents tests, cette recherche mettait 5 moins de temps pour SQL Server que sous PostgreSQL.
Requête SQL Server :
SELECT
D1.NOM_DEPT + ' / ' + D2.NOM_DEPT AS NOMS,
D1.GEOM.STUnion(D2.GEOM) AS GEO
FROM [S_GEO].[DEPARTEMENT] AS D1
JOIN [S_GEO].[DEPARTEMENT] AS D2
ON D1.GEOM.STDistance(D2.GEOM) < 5000
AND D1.GEOM.STTouches(D2.GEOM) = 0
AND D1.[GID] < D2.GID
Requête PostgreSQL :
SELECT
D1.nom_dept || ' / ' || D2.nom_dept AS NOMS,
ST_Union(D1.geom, D2.geom) AS GEO
FROM s_geo.departement AS D1
JOIN s_geo.departement AS D2
ON ST_Distance(D1.geom, D2.geom) < 5000
AND ST_Touches(D1.geom, D2.geom) = false
AND D1.gid < D2.gid
Durée (ms) | pour 1 client | pour 16 clients |
---|---|---|
SQL Server | 3 765 | 10 811 |
PostgreSQL | 16 199 | 63 832 |
Rapport PostgreSQL / SQL Server | 430 % | 590 % |
Ce test donne l'avantage à SQL Server dans les mêmes proportions que dans les tests originaux. Cet écart est encore plus important lorsque l'on lance 16 requêtes en parallèle.
Recherche des communes intérieures au département faisant au moins une surface de 34 567 890 m² (Q6)
Dans les tests sur Windows, le test Q6 était 4,5 fois plus rapide sous SQL Server que PostgreSQL.
Requête SQL Server :
SELECT CODE_COM, NOM_COM, C.CODE_DEPT, C.NOM_DEPT, C.GEOM
FROM S_GEO.COMMUNE AS C
JOIN S_GEO.DEPARTEMENT AS D
ON C.CODE_DEPT = D.CODE_DEPT
AND C.GEOM.STIntersects(D.GEOM.STBoundary()) = 0
WHERE C.GEOM.STArea() > 34567890
Requête PostgreSQL :
SELECT CODE_COM, NOM_COM, C.CODE_DEPT, C.NOM_DEPT, C.GEOM
FROM S_GEO.COMMUNE AS C
JOIN S_GEO.DEPARTEMENT AS D
ON C.CODE_DEPT = D.CODE_DEPT
AND ST_Intersects(C.GEOM, ST_Boundary(D.GEOM)) = false
WHERE ST_Area(C.GEOM) > 34567890
La requête SQL SERVER s'exécute un tout petit peu plus rapidement sur PostgreSQL pour une requête. Toutefois les performances s'effondrent avec la charge.
L'utilisateur thewild a proposé une amélioration de la requête en utilisant la fonction PostGIS optimisée ST_ContainsProperly
.
La requête PostgreSQL devient :
SELECT CODE_COM, NOM_COM, C.CODE_DEPT, C.NOM_DEPT, C.GEOM
FROM S_GEO.COMMUNE AS C
JOIN S_GEO.DEPARTEMENT AS D
ON C.CODE_DEPT = D.CODE_DEPT
AND ST_ContainsProperly(D.GEOM, C.GEOM) = true
WHERE ST_Area(C.GEOM) > 34567890
Les performances sont bien meilleures et sont stables lors de la montée en charge.
Durée (ms) | pour 1 client | pour 16 clients |
---|---|---|
SQL Server | 1 933 | 6 328 |
PostgreSQL originale | 1 691 | 13 209 |
PostgreSQL optimisée | 376 | 661 |
Rapport PostgreSQL / SQL Server | 19 % | 10 % |
Dans nos tests, c'est PostgreSQL qui s'en tire bien mieux en étant 5 fois plus rapide que SQL Server.
Quelle est la commune au barycentre de chaque département ? (Q7)
Il y a un an, cette requête était vraiment le point fort SQL Server qui mettait 63 fois moins de temps à exécuter le test que PostgreSQL.
Requête SQL Server :
SELECT CODE_COM, NOM_COM, C.CODE_DEPT, C.NOM_DEPT, C.GEOM
FROM S_GEO.COMMUNE AS C
JOIN S_GEO.DEPARTEMENT AS D
ON C.CODE_DEPT = D.CODE_DEPT
AND C.GEOM.STIntersects(D.GEOM.STCentroid()) = 1;
Requête PostgreSQL :
SELECT CODE_COM, NOM_COM, C.CODE_DEPT, C.NOM_DEPT, C.GEOM
FROM S_GEO.COMMUNE AS C
JOIN S_GEO.DEPARTEMENT AS D
ON C.CODE_DEPT = D.CODE_DEPT
AND ST_Intersects(C.GEOM, ST_Centroid(D.GEOM)) = true;
Durée (ms) | pour 1 client | pour 16 clients |
---|---|---|
SQL Server originale | 111 | 362 |
PostgreSQL originale | 62 | 103 |
Rapport PostgreSQL / SQL Server | 55 % | 29 % |
Comme pour la requête précédente, l'utilisateur thewild a proposé une amélioration de la requête. Nous utilisons cette fois-ci une CTE pour calculer en premier le barycentre de tous les départements.
La requête PostgreSQL devient :
WITH D AS (
SELECT CODE_DEPT, ST_Centroid(geom) AS GEOM FROM S_GEO.DEPARTEMENT
)
SELECT CODE_COM, NOM_COM, C.CODE_DEPT, C.NOM_DEPT, C.GEOM
FROM S_GEO.COMMUNE AS C
JOIN d
ON C.CODE_DEPT = D.CODE_DEPT
AND ST_Intersects(C.GEOM, d.GEOM) = true;
Nous utilisons la même méthode pour la requête SQL Server :
WITH D AS (
SELECT CODE_DEPT, GEOM.STCentroid() AS GEOM FROM S_GEO.DEPARTEMENT
)
SELECT CODE_COM, NOM_COM, C.CODE_DEPT, C.NOM_DEPT, C.GEOM
FROM S_GEO.COMMUNE AS C
JOIN D
ON C.CODE_DEPT = D.CODE_DEPT
AND C.GEOM.STIntersects(D.GEOM) = 1;
Durée (ms) | pour 1 client | pour 16 clients |
---|---|---|
SQL Server optimisée | 112 | 359 |
PostgreSQL optimisée | 33 | 51 |
Rapport PostgreSQL / SQL Server | 29 % | 14 % |
Que ce soit avec la requête originale ou optimisée, PostgreSQL est bien plus rapide que SQL Server. Il est même 7 fois plus rapide pour 16 clients.
Quelle est la commune dont la surface est la plus proche de 6 666 666 m² (Q8)
Ce test donnait une fois de plus l'avantage à SQL Server sous Windows, 2 fois plus rapide que PostgreSQL.
Requête SQL Server :
WITH T AS (
SELECT
CODE_COM, INSEE_COM, NOM_COM, GEOM.STArea() AS SURFACE, GEOM,
RANK() OVER(ORDER BY ABS(GEOM.STArea() - 6666666)) AS RANK_DIF
FROM S_GEO.COMMUNE
)
SELECT CODE_COM, INSEE_COM, NOM_COM, GEOM, SURFACE
FROM T
WHERE RANK_DIF = 1
Requête PostgreSQL :
WITH T AS (
SELECT
CODE_COM, INSEE_COM, NOM_COM, ST_Area(GEOM) AS SURFACE, GEOM,
RANK() OVER(ORDER BY ABS(ST_Area(GEOM) - 6666666)) AS RANK_DIF
FROM S_GEO.COMMUNE
)
SELECT CODE_COM, INSEE_COM, NOM_COM, GEOM, SURFACE
FROM T
WHERE RANK_DIF = 1;
Durée (ms) | pour 1 client | pour 16 clients |
---|---|---|
SQL Server | 592 | 8 354 |
PostgreSQL | 115 | 200 |
Rapport PostgreSQL / SQL Server | 19 % | 2,4 % |
En s'exécutant sous Linux, c'est maintenant PostgreSQL qui est plus rapide : 5 fois en requête unique, et 42 fois pour 16 requêtes simultanées.
Calcul de la longueur de routes pour toutes les catégories sauf inconnues (Q9)
Lors du premier test, les deux SGBDR étaient à égalité.
Requête SQL Server :
SELECT CLASS_ADM, SUM(GEOM.STLength()) / 1000 AS LONGUEUR_KM
FROM S_RTE.TRONCON_ROUTE
WHERE CLASS_ADM <> 'Sans objet'
GROUP BY CLASS_ADM
Requête PostgreSQL :
SELECT CLASS_ADM, SUM(ST_Length(GEOM)) / 1000 AS LONGUEUR_KM
FROM S_RTE.TRONCON_ROUTE
WHERE CLASS_ADM <> 'Sans objet'
GROUP BY CLASS_ADM
Durée (ms) | pour 1 client | pour 16 clients |
---|---|---|
SQL Server | 1 393 | 23 775 |
PostgreSQL | 81 | 356 |
Rapport PostgreSQL / SQL Server | 5,9 % | 1,6 % |
Sur Linux, PostgreSQL est bien plus rapide que SQL Server. Ce rapport monte à 67 avec 16 requêtes concurrentes !
Calcul de la longueur de routes par département et numéro de route (Q10)
Pour le test Q10, SQL Server était, sur Windows, 6 fois plus rapide que PostgreSQL.
Requête SQL Server :
SELECT
D.CODE_DEPT, NUM_ROUTE,
SUM(TR.GEOM.STLength()) / 1000 AS LONGUEUR_KM
FROM S_RTE.TRONCON_ROUTE AS TR
JOIN S_GEO.DEPARTEMENT AS D
ON TR.GEOM.STIntersects(D.GEOM) = 1
GROUP BY D.CODE_DEPT, NUM_ROUTE
ORDER BY CODE_DEPT, NUM_ROUTE
Requête PostgreSQL originale :
SELECT
D.CODE_DEPT, NUM_ROUTE,
SUM(ST_Length(TR.GEOM)) / 1000 AS LONGUEUR_KM
FROM S_RTE.TRONCON_ROUTE AS TR
JOIN S_GEO.DEPARTEMENT AS D
ON ST_Intersects(TR.GEOM, D.GEOM) = true
GROUP BY D.CODE_DEPT, NUM_ROUTE
ORDER BY CODE_DEPT, NUM_ROUTE
Cette requête a également été optimisée, car il utilisait de nombreux fichiers temporaires. Néanmoins, cette optimisation n'a pas eu d'impact sur le temps passé par le SGBDR à traiter la demande.
Requête PostgreSQL optimisée :
SELECT d.code_dept, routes.num_route, routes.longueur_km
FROM s_geo.departement AS d,
LATERAL (
SELECT num_route, SUM(ST_Length(tr.geom)) / 1000 AS longueur_km
FROM s_rte.troncon_route AS tr
WHERE ST_Intersects(TR.GEOM, D.GEOM)
GROUP BY d.code_dept, num_route
) routes
ORDER BY code_dept, num_route;
Durée (ms) | pour 1 client | pour 2 clients | pour 16 clients |
---|---|---|---|
SQL Server | 14 065 | 26 446 | 208 518 |
PostgreSQL | 29 467 | 29 777 | 102 075 |
Rapport PostgreSQL / SQL Server | 210 % | 113 % | 49 % |
Si SQL Server est 2 fois plus rapide en requête unique, dès le lancement avec 2 requêtes concurrentes, les performances sont équivalentes.
Au delà de 2 requêtes concurrentes, la parallélisation des requêtes par SQL Server n'est plus possible et PostgreSQL se montre 2 fois plus rapide.
Sauvegardes et restaurations
Frédéric Brouard avait constaté des sauvegardes et restaurations 2 à 4 fois plus rapides, suivant les cas, en SQL Server par rapport à PostgreSQL.
Il ne maitrisait cependant pas bien les commandes PostgreSQL et leur fonctionnement.
Tout d'abord, la commande pg_dump
ne bloque pas l'activité sur la base de données. Le niveau de verrou pris par cette commande est le plus bas. Seules les opérations les plus lourdes peuvent-être bloquées, telles la suppression d'une table ou l'ajout d'une colonne sans valeur par défaut.
Il est donc tout à fait possible pour pg_dump
de se lancer si une transaction est en cours et donc de sauvegarder une base de données à chaud avec PostgreSQL.
Les opérations de sauvegardes et restaurations effectuées par SQL Server sont systématiquement parallélisées. Afin de comparer au mieux les SGBDR, nous avons choisi d'effectuer pour PostgreSQL, des sauvegardes et restaurations parallélisées en mode directory
. Nous comparons les performances avec ou sans compression.
Pour ces tests, nous avons utilisé l'utilitaire multitime
. Il permet de calculer le temps que prend une commande comme le fait la commande time
. Il donne en plus les temps minimum, moyen, maximum ainsi que le temps médian et l'écart type des 3 temps suivants :
real
: le temps passé entre le moment où la commande est lancée, et la fin de son exécution,user
: le temps CPU passé par le programme en modeuser
,sys
: le tempssystem
, c'est le temps passé en traitement par le système d'exploitation.
La valeur médiane du temps réel, real
, nous a semblé la plus significative et a été retenue pour comparer les temps pris par les sauvegardes et restaurations des deux moteurs.
SQL Server
Sauvegarde SQL Server sans compression :
BACKUP DATABASE DB_GEO TO DISK = 'DB_GEO_SQLSERVER.BAK'
Sauvegarde SQL Server avec compression :
BACKUP DATABASE DB_GEO TO DISK = 'DB_GEO_SQLSERVER_COMP.BAK2' WITH COMPRESSION
Restauration SQL Server sans compression :
RESTORE DATABASE DB_GEO FROM DISK = 'DB_GEO_SQLSERVER.BAK'
Restauration SQL Server avec compression :
RESTORE DATABASE DB_GEO FROM DISK = 'DB_GEO_SQLSERVER.BAK2'
PostgreSQL
Sauvegarde PostgreSQL dans un répertoire, en parallélisant sur 8 threads, sans compression :
pg_dump -Fd -f db_geo_dir -j 8 -Z 0 db_geo
Sauvegarde PostgreSQL dans un répertoire, en parallélisant sur 8 threads, avec compression :
pg_dump -Fd -f db_geo_dir_zip -j 8 -Z 1 db_geo
Restauration PostgreSQL, en parallélisant sur 8 threads, sans compression :
dropdb --if-exists db_geo_dir
createdb db_geo_dir
pg_restore -d db_geo_dir -j 8 db_geo_dir
Restauration PostgreSQL, en parallélisant sur 8 threads, sans compression :
dropdb --if-exists db_geo_dir_zip
createdb db_geo_dir_zip
pg_restore -d db_geo_dir_zip -j 8 db_geo_dir_zip
Performances
Taille des sauvegardes | Sans compression | Avec compression |
---|---|---|
SQL Server | 1 Go | 363 Mo |
PostgreSQL | 1,7 Go | 393 Mo |
Rapport PostgreSQL / SQL Server | 170 % | 108 % |
Les tailles des fichiers de sauvegardes sont plus faibles sur SQL Server, que ce soit avec ou sans compression.
Sauvegardes | SQL Server | PostgreSQL | Rapport PostgreSQL / SQL Server |
---|---|---|---|
Sans compression | 3 164 | 4 504 | 142 % |
Avec compression | 4 504 | 6 416 | 142 % |
Restaurations | SQL Server | PostgreSQL | Rapport PostgreSQL / SQL Server |
---|---|---|---|
Sans compression | 21 696 | 10 462 | 48 % |
Avec compression | 20 109 | 11 082 | 55 % |
L'utilisation de la parallélisation offerte par le mode directory
améliore considérablement les performances des sauvegardes en PostgreSQL.
Si les performances de sauvegardes restent meilleures avec SQL Server, les performances de restaurations sont meilleures sur PostgreSQL.
Commentaires: