Ce document compare les performances de quelques BD (eXist, BaseX, Mysql), sans avoir la prétention de se positionner comme un benchmark complet.
Le problème de performance décrit ici est apparu lors de la publication du projet XML soumis aux étudiants de la filière MIAGE de Nice en 2013.
Dans ce projet, les données XML ci-contre devaient être chargées dans une BD native XML, et les performances obtenues étaient visiblement déplorables.
Comme l'enjeu de ce projet n'est pas de résoudre des problèmes de performance, mais de réaliser une application, un autre jeu de données a été proposé.
Il n'en reste pas moins que des questions légitimes concernant les performances des BD natives XML sont soulevées, et afin d'éviter des conclusions hâtives et non nécessairement fondées, qui affirmeraient que les BD relationnelles sont plus performantes, il est proposé de restituer ici quelques éléments tangibles de comparaison.
Les bases de données comparées sont :
Les données comparées proviennent du jeu de données de recensement des équipements sportifs français, disponibles en XML. Comme le montre l'exemple, il s'agit d'une structure plate qu'on peut insérer facilement dans une BD relationnelle. Ces données ont donc été chargées telles quelles dans eXist et BaseX, et dans une table unique Mysql. Pour chacune des BD, aucune autre adaptation n'a été réalisée (création d'index spécifique, ou éclatement en plusieurs tables pour Mysql).
Les requêtes comparées sont des requêtes XQuery et une transcription équivalente en SQL. Comme chaque produit dispose d'une interface permettant de soumettre directement les requêtes, aucun programme hôte n'a été utilisé.
Les mesures comparées sont brutes et à prendre avec précaution ; en effet :
C'est pourquoi il faut considérer ces résultats avec la plus grande précaution, et que ce document ne constitue en rien un benchmarking sérieux, mais se contente de délivrer simplement quelques mesures en guise de premiers éléments de comparaison.
Le fichier XML a été chargé dans deux BD XML et un SGBDR.
Extrait du fichier :
<?xml version="1.0" encoding="UTF-8"?> <NewDataSet> <Export_OpenDataV2> <RegionId>91</RegionId> <RegLib>Languedoc-Roussillon</RegLib> <DepCode>34</DepCode> <DepLib>Hérault</DepLib> <ComInsee>34028</ComInsee> <ComLib>Bédarieux</ComLib> <InsNumeroInstall>340280001</InsNumeroInstall> <InsNom>Complexe Sportif René Char</InsNom> <InsNoVoie /> <InsLibelleVoie>Boulevard Jean Moulin</InsLibelleVoie> <InsLieuDit /> <InsCodePostal>34600</InsCodePostal> <InsDateMaj>2012-06-18T00:00:00+02:00</InsDateMaj> <EquipementId>1833</EquipementId> <EquNom>Gymnase Municipal Complexe Sportif René Char</EquNom> <EquNomBatiment>Complexe Sportif René Char</EquNomBatiment> <EquipementTypeId>83</EquipementTypeId> <EquipementTypeLib>Salle multisports</EquipementTypeLib> <EquipementFiche>generique</EquipementFiche> <NatureTypeID>7</NatureTypeID> <NatureLibelle>Intérieur</NatureLibelle> <NatureSolId>10</NatureSolId> <NatureSolLib>Synthétique (hors gazon)</NatureSolLib> <EquNbEquIdentique>1</EquNbEquIdentique> <EquGpsX>3.15450660</EquGpsX> <EquGpsY>43.60991085</EquGpsY> <EquDateMaj>2012-06-18T00:00:00+02:00</EquDateMaj> <ActiviteId>30</ActiviteId> <ActLib>Basket-Ball</ActLib> <EquActivitePraticable>true</EquActivitePraticable> <EquActivitePratique>true</EquActivitePratique> <EquActiviteSalleSpe>false</EquActiviteSalleSpe> <ActNivLib>Compétition départementale</ActNivLib> </Export_OpenDataV2> </NewDataSet>
Requête | Résultats | Commentaires | ||
---|---|---|---|---|
Comptage des entrées | ||||
XQuery | count(//Export_OpenDataV2) |
eXist | 1.037 s | 1 item (qui contient la réponse = 463322) |
BaseX | 0.045 s | |||
SQL | SELECT count(*) FROM openData.Export_OpenDataV2; |
Mysql | 0.106 s | |
Filtre sur une région | ||||
XQuery | //Export_OpenDataV2[RegionId=91] |
eXist | 25 s | 22 232 items |
BaseX | 1.8 s | |||
SQL | SELECT * FROM openData.Export_OpenDataV2 WHERE RegionId = "91"; |
Mysql | 1.8 s | |
Sélection des n° de région uniques | ||||
XQuery | for $r in distinct-values(//RegionId) order by $r cast as xs:integer return $r |
eXist | 26.5 s | 33 items |
BaseX | 1.7 s | |||
SQL | SELECT DISTINC RegionId FROM openData.Export_OpenDataV2 ORDER BY CAST(RegionId AS UNSIGNED); |
Mysql | 1.29 s | |
Sélection des activités uniques | ||||
XQuery | for $act in distinct-values(//ActLib) order by $act return |
eXist | 25.5 s | 232 items |
BaseX | 2.1 s | |||
SQL | SELECT DISTINCT ActLib FROM openData.Export_OpenDataV2 ORDER BY ActLib; |
Mysql | 2.1 s |
BaseX et Mysql donnent des résultats comparables.
eXist malheureusement ne donne pas de résultats satisfaisants : la première requête de comptage donne une durée d'exécution 20 x supérieurs à BaseX et 10 x supérieurs à Mysql, ce qui n'est pas acceptable étant donné qu'on espère que chaque item soit proprement indexé sans besoin de définir quoi que ce soit dans la BD. Les autres requêtes montrent qu'eXist n'arrive pas à produire le résultat d'une requête simple en des temps comparables à BaseX et Mysql.
eXist offre cependant des moyens d'améliorer les performances, en créant des index spécifiques mais aussi dans l'optimisation de l'écriture des requêtes. Bien qu'aucune de ces améliorations n'aient été mises en œuvre dans ces tests, il semble raisonnable de reconsidérer l'utilisation d'eXist (2.1) en production sur d'importants volumes de données, à moins que l'équipe de développeurs d'eXist ne produise des améliorations significatives sur une future version.
Toutefois, quand on compare les résultat de Mysql et de BaseX, on constate que les performances d'une BD native XML peuvent être comparables à celles d'une BD relationnelle. S'il fallait comparer les 2 systèmes plus loin, on pourrait comparer les langages XQuery et SQL : XQuery dispose d'une capacité d'expression sans limite (XQuery étant un langage turing-complet) et bien meilleur que SQL.
A titre d'exemple réel, le lecteur est invité à constater de visu les performances rendues par l'application Markmail, constitué de quelques 66 millions de messages XMLisés et interrogés en XQuery. Comme quoi, les produits commerciaux peuvent aussi montrer que les performances XML-XQuery sont largement à la hauteur.