1 pièce(s) jointe(s)
PostgreSQL surpasserait MySQL et MariaDB en lecture ?
PostgreSQL surpasse-t-il MySQL et MariaDB en lecture ?
Un ingénieur logiciel partage son test de performance des trois systèmes de gestion de bases de données
Faire le choix de la base de données à utiliser dans un projet peut être un choix difficile pour un développeur dans des petites équipes de développements où une même personne peut accumuler plusieurs rôles à la fois. Dans certaines équipes il n’est pas rare que le développeur joue en même temps le rôle de concepteur de bases de données par exemple. Pour aider ses pairs dans leur choix technologique, un ingénieur logiciel partage les résultats de son test de performance avec la communauté. Ce qui a retenu son attention, souligne-t-il, c’est les performances de Postgres en lecture. D’après les résultats publiés par l’auteur du test de performance, MariaBD et MySQL ont pris les devants quand il s’agit des requêtes d’écriture en base de données. Cependant pour les requêtes de lecture en base de données, Postgres s’est démarqué de manière assez nette des deux autres aussi bien pour des requêtes simples que les requêtes complexes.
L’environnement utilisé par l’auteur du Benchmark est Ubuntu Wily Werwolf qui est la version 15.10 du système d’exploitation utilisé sur une machine avec un environnement processeur monocœur et une capacité de 1024 Mo de mémoire RAM. Pour les versions des systèmes de gestion de bases de données utilisés, il s’agit de la version 10.1.11 de MaraiDB, la version 5.7.10 de MySQL et de la version 9.5.0 de Postgres. La figure suivante représente les différentes requêtes de lecture en base de données qui ont été faites sur les trois systèmes de gestion de bases de données.
Les bons résultats obtenus avec Postgres pourraient s’expliquer d’après l’auteur du benchmark par le fait que ce système de gestion de bases de données respecte les standards SQL, en tout cas plus que les deux autres.
Source : résultats du benchmark
Et vous ?
:fleche: Avez-vous testé les performances de ces différents systèmes de gestion de bases de données ?
:fleche: Vos résultats confirment-ils les performances de Postgres par rapport aux deux autres ?
Voir aussi
:fleche: la rubrique Bases de données
L'auteur du deuxième Quote est bien escartefigue et non Victor Vincent
Bonsoir,
Citation:
Envoyé par Victor Vincent
Les bons résultats obtenus avec Postgres pourraient s’expliquer d’après l’auteur du benchmark par le fait que ce système de gestion de base de données respecte les standards SQL, en tout cas plus que les deux autres.
Bigre ! Qu’est-ce que la norme SQL vient faire dans cette histoire ? Elle traite du Quoi, plutôt que du Comment ! Si l’auteur parlait de la supériorité de l’optimiseur du SGBD, de la structure des espaces physiques, index et autres éléments sous le capot, soit. Mais pour comparer, encore faut-il être très pointu à la fois sur toutes ces choses quant aux SGBD dont il est question, or il est pratiquement impossible d’être spécialiste dans les tréfonds de plus d’un SGBD. Ainsi, il est des études comparatives et autres benchmarks qui laissent songeur, tel celui-ci...
Citation:
Envoyé par escartefigue
Si la performance des requêtes est un critère de choix, alors pourquoi privilégier les requêtes en lecture, plutôt que celles en màj ? pour des infocentres, oui, mais en ce cas aucun des 2 sgbd cités n'est concerné.
Voilà des paroles frappées au coin du bon sens !
Pour ce qu’il en est de lire le plus vite possible des tables comme celle du benchmark (j’utilise le singulier : « celle », car je n’ai pas vu de jointure ou d’union, mais peut-être suis-je mauvaise langue, la table « testing » est-elle en fait une vue de jointure et/ou d’union ? :P), les fichiers plats (même sophistiqués comme ceux qui utilisent VSAM d’IBM) sont sans doute les meilleurs candidats...
Mais, comme le sous-entend escartefigue, faire des mises à jour concurrentes, avec célérité, en toute sécurité et sans gêner les voisins, c’est une autre paire de manches, comparer en toute objectivité devient bigrement compliqué, il faut faire intervenir des DBA expérimentés, spécialistes de leur SGBD respectif...
Cela dit, comme le fait encore observer escartefigue, MySQL est sans doute un choix risqué, mais, pour ma part, ne l’ayant pas suffisamment secoué pour prétendre être véritablement spécialiste de ce SGBD, je suis obligé de suivre la proposition 7 de Wittgenstein (même chose au sujet de PostgreSQL)...
D’amour mourir me font, belle Marquise, vos beaux yeux...
Bonsoir,
Citation:
Envoyé par Artemus24
6) quand tu as trois tables en jointure, il y a un ordre à respecter.
En général, on commence par la table charnière (je réutilise ton vocabulaire).
Et ensuite, on fait le jointure sur les autres tables.
Pourquoi respecter un tel ordre ? Et s’il y a 10 tables « charnières » à joindre, par quel bout commence-t-on ? Au passage, je fais observer que la jointure naturelle est une opération commutative et associative, faisant que l’ordre ne joue pas.
Citation:
Envoyé par Artemus24
Inversement, si tu veux optimiser tes accès, commence par les tables les plus petites.
S’il s’agit là encore d’un ordre à respecter, autant dire qu’un optimiseur s’en tamponne le coquillard ! Il sait ce qu’il a à faire et comment le faire.
Citation:
Envoyé par Gugelhupf
Citation:
Envoyé par Artemus24
Pourquoi faire un "where M.id = 40" ?
Car en faisant cela, tu récupères tout, puis ensuite, tu sélectionnes ce dont tu as besoin.
7. Pourquoi faire un "where M.id = 40" ? : parce que id = 40 n'est pas une condition de jointure, mais un élément variable. Je n'ai pas testé la différence entre les performances entre
ON et
WHERE, mais je suis sur que le SGBD optimise cela à la lecture de la requête.
Vous avez parfaitement raison, Gugelhupf, c’est bien le SGBD qui optimise.
En fait, "where M.id = 40" correspond à l’opération relationnelle de restriction. Il est évident qu’un optimiseur quel qu’il soit va commencer par effectuer cette opération qui est la plus rentable de toutes quant aux performances (sous réserve bien sûr que l’on ait défini l’index ad-hoc).
Ainsi, que l’on code « Belle Marquise, vos beaux yeux me font mourir d’amour » :
SELECT
P.*,
M.nom AS nom_medecin,
M.prenom AS prenom_medecin
FROM t_medecin M
JOIN t_charniere_medecin_patient MP
ON M.id = MP.id_medecin
JOIN t_patient P
ON P.id = MP.id_patient
WHERE M.id = 40
;
Ou bien « D’amour mourir me font, belle Marquise, vos beaux yeux » :
SELECT
P.*,
M.nom AS nom_medecin,
M.prenom AS prenom_medecin
FROM t_medecin M, t_charniere_medecin_patient MP, t_patient P
WHERE M.id = MP.id_medecin
AND P.id = MP.id_patient
AND M.id = 40
;
ou encore « Vos yeux beaux d’amour me font, belle Marquise, mourir » :
SELECT
P.*,
M.nom AS nom_medecin,
M.prenom AS prenom_medecin
FROM t_charniere_medecin_patient MP
INNER JOIN t_medecin M
ON M.id = MP.id_medecin
AND M.id = 40
INNER JOIN t_patient P
ON P.id = MP.id_patient
WHERE M.id = 40;
Eh bien, un optimiseur n’en a cure car, comme aurait dit Monsieur de La Palice, sa mission c’est ... d’optimiser ! Dans tous les cas, il applique donc d’abord la restriction très juteuse « where M.id = 40 », ce que montre bien un EXPLAIN, même avec MySQL :
1re requête :
http://www.fsmwarden.com/developpez_...lain_mysql.png
2e requête :
http://www.fsmwarden.com/developpez_...lain_mysql.png
3e requête :
http://www.fsmwarden.com/developpez_...lain_mysql.png
Citation:
Envoyé par Artemus24
une foreign key, c'est déjà un index
Les auteurs de MySQL en ont certes décidé ainsi, mais c’est un diktat insupportable, une erreur de leur part, ils confondent les niveaux, relationnel d’une part, physique d’autre part. Une clé étrangère (foreign key) d’une table T1 n’est pas un index, mais une référence à une clé candidate (voire une surclé) d’une table T2 (non nécessairement distincte de T1). On est en l’occurrence au niveau relationnel. Sorti de MySQL, que le DBA décide au niveau physique de mettre en œuvre pour T1 un index dont les colonnes sont celles de la clé étrangère, pourquoi pas, mais seulement en cas de nécessité, il est le seul juge.
Par exemple, avec PostgreSQL, sans index sur la colonne id_medecin, la requête ci-dessous va provoquer un balayage complet de la table t_charniere_medecin_patient :
select * from t_charniere_medecin_patient where id_medecin = 40 ;
=>
"Seq Scan on t_charniere_medecin_patient "
Avec un tel verdict de la part de l’optimiseur, on créera un index, mais là encore, c’est une décision du DBA (après tout, pour une table de quelques lignes, genre titres de civilité, le jeu n’en vaut sans doute pas la chandelle). Dans le cas présent, avec PostgreSQL, on codera par exemple :
create index t_charniere_medecin_patient_x1 on t_charniere_medecin_patient (id_medecin) ;
Et notre DBA peaufinera dans la soute, jusqu’à ce qu’il obtienne la performance recherchée. En passant, avant de s’occuper de la performance, afin d’éviter que cette table ne se transforme en « sac à tuples » (présence de doublons, donc mise en danger de l’algèbre relationnelle qui ne sait opérer correctement que sur des ensembles), il la dotera d’une clé primaire {id_medecin, id_patient} (avec pour conséquence la mise en œuvre implicite ou non de l’index de type UNIQUE correspondant...)
Citation:
5) tu fais une jointure, d'accord, mais j'aimerai que tu précises quel type de jointure.
Un "inner join", un "left outer join", autre chose ... Je n'aime pas les déclaratives par défaut.
Les sentiments ne sont pas de mise ! SQL est un langage pour lequel il existe une norme, et il y est écrit (cf. par exemple WG3:HBA-003 = H2-2003-305 = 5WD-02-Foundation-2003-09, WD 9075-2 (SQL/Foundation), September, 2003, aux pages 312-313) :
7.7 <joined table>
Function
Specify a table derived from a Cartesian product, inner join, or outer join.
Format
<joined table> ::=
<cross join>
| <qualified join>
| <natural join>
<cross join> ::=
<table reference> CROSS JOIN <table factor>
<qualified join> ::=
<table reference> [ <join type> ] JOIN <table reference> <join specification>
<natural join> ::=
<table reference> NATURAL [ <join type> ] JOIN <table factor>
<join specification> ::=
<join condition>
| <named columns join>
<join condition> ::= ON <search condition>
<named columns join> ::= USING <left paren> <join column list> <right paren>
<join type> ::=
INNER
| <outer join type> [ OUTER ]
<outer join type> ::=
LEFT
| RIGHT
| FULL
<join column list> ::=
<column name list>
Syntax Rules
[...]
3) If a <qualified join> or <natural join> is specified and a <join type> is not specified, then INNER is implicit.
[...]
La norme ayant décrété (dès SQL:1992, il y a donc belle lurette !) qu’INNER était implicite, chacun est libre d’en faire usage ou non. Maintenant, si les règles en vigueur dans l’entreprise imposent INNER (ou NATURAL ou USING, etc.), chacun devra évidemment se conformer à ces règles.
Merci à l'éditeur de la newsletter de compléter
Bonjour,
Ce billet est publié dans la newsletter, mais n'y sont affichés que les 10 premiers commentaires, selon l'ordre chronologique :
Merci à l'éditeur de la newsletter d'agir en conséquence, afin que tout le monde puisse voir la suite, laquelle est loin d'être inintéressante.