<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Benjamin Geer</title>
    <link>https://benjamingeer.name/fr/</link>
    <description>Recent content on Benjamin Geer</description>
    <generator>Hugo</generator>
    <language>fr-FR</language>
    <lastBuildDate>Mon, 30 Mar 2026 13:02:25 +0200</lastBuildDate>
    <atom:link href="https://benjamingeer.name/fr/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Optimiser des requêtes PostgreSQL avec un jeu de données ouvert</title>
      <link>https://benjamingeer.name/fr/post/bref/</link>
      <pubDate>Tue, 10 Mar 2026 13:49:30 +0100</pubDate>
      <guid>https://benjamingeer.name/fr/post/bref/</guid>
      <description>&lt;h2 class=&#34;heading&#34; id=&#34;aperçu&#34;&gt;&#xA;  Aperçu&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#aper%c3%a7u&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Ce billet illustre brièvement quelques techniques d&amp;rsquo;optimisation des bases de&#xA;données, en utilisant la &lt;a href=&#34;https://zenodo.org/records/14628510&#34; target=&#34;_blank&#34;&gt;BRÉF (Base Révisée des Élu·es de&#xA;France)&lt;/a&gt;, qui contient des données sur les&#xA;représentant·es élu·es en France de 1948 à 2020. La BRÉF est basée sur des&#xA;données publiques, dans lesquelles une équipe de chercheurs a corrigé&#xA;&lt;a href=&#34;https://hal.science/hal-02886580v2&#34; target=&#34;_blank&#34;&gt;beaucoup d&amp;rsquo;erreurs et d&amp;rsquo;incohérences&lt;/a&gt;.&#xA;Elle est publiée sous la forme d&amp;rsquo;une base de données&#xA;&lt;a href=&#34;https://www.postgresql.org&#34; target=&#34;_blank&#34;&gt;PostgreSQL&lt;/a&gt; qui comprend plusieurs tables et&#xA;offre beaucoup de possibilités de jointures et d&amp;rsquo;optimisations.&lt;/p&gt;&#xA;&lt;p&gt;J&amp;rsquo;utiliserai ici cette base de données pour développer et optimiser une requête&#xA;SQL comprenant plusieurs jointures, pour obtenir des informations sur les maires&#xA;et les communes où elles et ils ont été élu·es. Je construirai la requête à&#xA;partir d&amp;rsquo;éléments plus simples, que j&amp;rsquo;optimiserai au fur et à mesure. Dans le&#xA;cadre de cet exercice, je pars du principe que nous ne pouvons pas modifier le&#xA;schéma de la base de données et que nous sommes prêts à payer un certain coût,&#xA;en espace de stockage et en termes de performances de mise à jour, pour&#xA;améliorer les performances des requêtes (d&amp;rsquo;autant plus que la base de données&#xA;n&amp;rsquo;est pas très grande et que les mises à jour sont rares). Je me concentrerai&#xA;donc sur ce que nous pouvons faire en créant des index. Pour identifier et&#xA;tester des optimisations possibles, nous aurons deux sources d&amp;rsquo;information :&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Les plans d&amp;rsquo;exécution de PostgreSQL, que nous pouvons obtenir en utilisant la&#xA;commande &lt;code&gt;EXPLAIN&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Des tests de performance exécutés par mon outil&#xA;&lt;a href=&#34;https://benjamingeer.name/fr/post/sqlstopwatch/&#34;&gt;sqlstopwatch&lt;/a&gt;, qui exécute&#xA;des requêtes à maintes reprises et indique le temps de réponse moyen de chaque&#xA;requête.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;optimiser-une-requête-simple&#34;&gt;&#xA;  Optimiser une requête simple&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#optimiser-une-requ%c3%aate-simple&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Dans la terminologie du BRÉF,&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;le &lt;strong&gt;mandat&lt;/strong&gt; correspond à la position élective (député, sénateur, etc.) tandis&#xA;que le terme &lt;strong&gt;fonction&lt;/strong&gt; recouvre une fonction exécutive dans le cadre d&amp;rsquo;un&#xA;mandat. Ainsi, une personne peut être élue à la position de conseiller·e&#xA;municipal·e, puis à celle de maire au sein de ce conseil municipal.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;Il y a donc des tables qui s&amp;rsquo;appellent &lt;code&gt;Mandate&lt;/code&gt; et &lt;code&gt;Function&lt;/code&gt; et nous&#xA;commencerons par celles-ci.&lt;/p&gt;&#xA;&lt;p&gt;Trouvons d&amp;rsquo;abord toutes les fonctions de type &lt;code&gt;MAIRE&lt;/code&gt;. Nous utiliserons&#xA;&lt;a href=&#34;https://www.postgresql.org/docs/18/sql-explain.html&#34; target=&#34;_blank&#34;&gt;&lt;code&gt;EXPLAIN ANALYZE&lt;/code&gt;&lt;/a&gt; pour&#xA;que Postgres exécute la requête, puis affiche le plan d&amp;rsquo;exécution (&lt;code&gt;EXPLAIN&lt;/code&gt;) en&#xA;indiquant le temps nécessaire à son exécution (&lt;code&gt;ANALYZE&lt;/code&gt;).&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;EXPLAIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ANALYZE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;MandateId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Function&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;WHERE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;FunctionType&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;MAIRE&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;QUERY PLAN&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Seq Scan on &amp;#34;Function&amp;#34;  (cost=0.00..5596.96 rows=113829 width=4)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  (actual time=0.010..17.567 rows=114192 loops=1)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Filter: ((&amp;#34;FunctionType&amp;#34;)::text = &amp;#39;MAIRE&amp;#39;::text)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Rows Removed by Filter: 158845&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Planning Time: 0.217 ms&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Execution Time: 20.136 ms&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Le plan d&amp;rsquo;exécution est un arbre et chaque node a un &lt;a href=&#34;https://www.postgresql.org/docs/18/using-explain.html#USING-EXPLAIN-BASICS&#34; target=&#34;_blank&#34;&gt;coût&#xA;estimé&lt;/a&gt;&#xA;dont les unités sont arbitraires. Il faut noter que « le coût d&amp;rsquo;un nœud père&#xA;comprend le coût de tous ses fils ». &lt;code&gt;Seq Scan&lt;/code&gt; veut dire que la base de données&#xA;parcourt toute la table &lt;code&gt;Function&lt;/code&gt; à la recherche de chaînes correspondantes.&#xA;Pour éviter cela, &lt;a href=&#34;https://www.postgresql.org/docs/current/sql-createindex.html&#34; target=&#34;_blank&#34;&gt;créons un&#xA;index&lt;/a&gt; sur la&#xA;colonne &lt;code&gt;FunctionType&lt;/code&gt;, puis exécutons &lt;code&gt;EXPLAIN ANALYZE&lt;/code&gt; à nouveau avec la même&#xA;requête. (Dans cet exercice nous nous limiterons à utiliser des index de type&#xA;B-Tree, que la commande &lt;code&gt;CREATE INDEX&lt;/code&gt; utilise par défaut.)&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INDEX&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;index_function&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Function&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;FunctionType&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Il en résulte un plan d&amp;rsquo;exécution différent :&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;QUERY PLAN&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Bitmap Heap Scan on &amp;#34;Function&amp;#34;  (cost=1286.60..4893.46 rows=113829 width=4)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  (actual time=3.764..11.449 rows=114192 loops=1)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Recheck Cond: ((&amp;#34;FunctionType&amp;#34;)::text = &amp;#39;MAIRE&amp;#39;::text)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Heap Blocks: exact=822&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -&amp;gt;  Bitmap Index Scan on index_function&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      (cost=0.00..1258.14 rows=113829 width=0)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      (actual time=3.589..3.589 rows=114192 loops=1)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        Index Cond: ((&amp;#34;FunctionType&amp;#34;)::text = &amp;#39;MAIRE&amp;#39;::text)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Planning Time: 0.314 ms&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Execution Time: 13.551 ms&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Postgres a effectué un parcours de &lt;em&gt;bitmap&lt;/em&gt;, que Tom Lane, un des développeurs&#xA;de Postgres, a expliqué dans &lt;a href=&#34;https://www.postgresql.org/message-id/12553.1135634231@sss.pgh.pa.us&#34; target=&#34;_blank&#34;&gt;ce message publié sur une liste de&#xA;diffusion&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Un parcours de bitmap récupère tous les pointeurs de n-uplets de l&amp;rsquo;index en&#xA;une seule fois, les trie en mémoire à l&amp;rsquo;aide d&amp;rsquo;une structure de données&#xA;appelée « bitmap », puis visite les n-uplets de la table dans l&amp;rsquo;ordre physique&#xA;de leur emplacement&amp;hellip; Si le bitmap devient trop volumineux, nous le&#xA;convertissons en bitmap « avec perte », dans lequel nous ne notons que les&#xA;pages contenant des n-uplets correspondants au lieu de noter chaque n-uplet&#xA;individuellement. Dans ce cas-là, quand nous lisons ces pages de la table, il&#xA;faut examiner chaque n-uplet de chaque page lue et revérifier la&#xA;condition du parcours pour déterminer les n-uplets à renvoyer.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;Ceci est plus efficace qu&amp;rsquo;un parcours de table, mais nous payons toujours le&#xA;prix de l&amp;rsquo;accès à la table pour récupérer les n-uplets (c&amp;rsquo;est-à-dire les lignes)&#xA;et celui de la revérification de la condition du parcours. Comme il ne nous faut&#xA;que la colonne &lt;code&gt;MandateId&lt;/code&gt;, nous pouvons la mettre elle aussi dans l&amp;rsquo;index, pour&#xA;créer un &lt;a href=&#34;https://www.postgresql.org/docs/18/indexes-index-only-scans.html&#34; target=&#34;_blank&#34;&gt;index&#xA;couvrant&lt;/a&gt; pour&#xA;cette requête :&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INDEX&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;index_function&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Function&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;FunctionType&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;INCLUDE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;MandateId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Cela nous donne un autre plan d&amp;rsquo;exécution :&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;QUERY PLAN&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Index Only Scan using index_function on &amp;#34;Function&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  (cost=0.42..4490.35 rows=115003 width=4)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  (actual time=0.027..7.354 rows=114192 loops=1)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Index Cond: (&amp;#34;FunctionType&amp;#34; = &amp;#39;MAIRE&amp;#39;::text)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Heap Fetches: 0&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Planning Time: 0.184 ms&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Execution Time: 9.025 ms&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Maintenant Postgres peut faire un parcours d&amp;rsquo;index seul, parce que toutes les&#xA;colonnes qu&amp;rsquo;il nous faut sont dans l&amp;rsquo;index. Cela semble être une&#xA;amélioration, mais faisons un test de performance pour vérifier. Testons&#xA;plusieurs requêtes qui cherchent différentes fonctions, y compris celle de&#xA;maire. Nous ferons le test d&amp;rsquo;abord sans index, puis avec chacun des index&#xA;ci-dessus.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;MandateId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Function&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;WHERE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;FunctionType&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;MAIRE&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;FETCH&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FIRST&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;750&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ROWS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ONLY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;MandateId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Function&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;WHERE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;FunctionType&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;MAIRE DELEGUE&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;FETCH&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FIRST&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;750&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ROWS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ONLY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;MandateId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Function&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;WHERE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;FunctionType&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;PRESIDENT DU CONSEIL REGIONAL&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;FETCH&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FIRST&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;750&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ROWS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ONLY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;MandateId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Function&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;WHERE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;FunctionType&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;PREMIER ADJOINT AU MAIRE&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;FETCH&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FIRST&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;750&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ROWS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ONLY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;figure&gt;&lt;img src=&#34;https://benjamingeer.name/fr/post/bref/functions-fr.svg&#34;&#xA;    alt=&#34;un diagramme à barres représentant des résultats de tests&#34; width=&#34;100%&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;Il est clair qu&amp;rsquo;il vaut mieux avoir un index que ne pas en avoir. Par rapport à&#xA;l&amp;rsquo;index qui ne contient que &lt;code&gt;FunctionType&lt;/code&gt;, celui qui comprend aussi &lt;code&gt;MandateId&lt;/code&gt;&#xA;(et permet donc un parcours d&amp;rsquo;index seul) ne change pas grand-chose pour&#xA;certaines valeurs de &lt;code&gt;FunctionType&lt;/code&gt;, mais il est plus de deux fois plus rapide&#xA;pour &lt;code&gt;MAIRE&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;trier&#34;&gt;&#xA;  Trier&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#trier&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Nous aimerions obtenir des résultats triés par date de début de fonction :&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;EXPLAIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ANALYZE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;MandateId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Function&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;WHERE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;FunctionType&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;MAIRE&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;ORDER&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;BY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;FunctionStartDate&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Sans index, la base de données indique que cette requête prend environ deux fois&#xA;plus de temps que sans le tri :&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;QUERY PLAN&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Sort  (cost=15354.29..15644.28 rows=115995 width=8)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      (actual time=32.564..37.109 rows=114192 loops=1)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Sort Key: &amp;#34;FunctionStartDate&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Sort Method: external merge  Disk: 2016kB&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -&amp;gt;  Seq Scan on &amp;#34;Function&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      (cost=0.00..5596.96 rows=115995 width=8)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      (actual time=0.016..17.797 rows=114192 loops=1)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        Filter: ((&amp;#34;FunctionType&amp;#34;)::text = &amp;#39;MAIRE&amp;#39;::text)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        Rows Removed by Filter: 158845&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Planning Time: 0.398 ms&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Execution Time: 40.132 ms&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Il est intéressant de noter que si nous utilisons l&amp;rsquo;index de la section&#xA;précédente avec cette requête, cela ne change pas le plan d&amp;rsquo;exécution cette&#xA;fois-ci. Postgres a décidé que notre index n&amp;rsquo;apportera probablement pas&#xA;d&amp;rsquo;avantage à cette requête. Pour que l&amp;rsquo;index vaille la peine d&amp;rsquo;être utilisé ici,&#xA;ajoutons-y la colonne &lt;code&gt;FunctionStartDate&lt;/code&gt;, pour que les entrées pour chaque type&#xA;de fonction soient triées par date de début dans l&amp;rsquo;index :&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INDEX&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;index_function&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Function&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;FunctionType&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;FunctionStartDate&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;INCLUDE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;MandateId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;QUERY PLAN&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Index Only Scan using index_function on &amp;#34;Function&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  (cost=0.42..4743.89 rows=115995 width=8)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  (actual time=0.052..9.744 rows=114192 loops=1)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Index Cond: (&amp;#34;FunctionType&amp;#34; = &amp;#39;MAIRE&amp;#39;::text)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Heap Fetches: 0&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Planning Time: 0.432 ms&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Execution Time: 12.275 ms&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Cela nous donne à nouveau un parcours d&amp;rsquo;index seul, qui semble plus efficace.&#xA;Faisons un test de performance pour comparer l&amp;rsquo;index précédent à celui-ci. Nous&#xA;utiliserons les requêtes de la section précédente, en ajoutant &lt;code&gt;ORDER BY &amp;quot;FunctionStartDate&amp;quot;&lt;/code&gt; à chacune d&amp;rsquo;elles.&lt;/p&gt;&#xA;&lt;figure&gt;&lt;img src=&#34;https://benjamingeer.name/fr/post/bref/functions-sorted-fr.svg&#34;&#xA;    alt=&#34;un diagramme à barres représentant des résultats de tests&#34; width=&#34;100%&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;Il semble que plus il y a de lignes à trier, plus il soit avantageux d&amp;rsquo;utiliser&#xA;un index qui est déjà trié dans l&amp;rsquo;ordre demandé par la clause &lt;code&gt;ORDER BY&lt;/code&gt;. Cet&#xA;avantage est très important dans le cas de &lt;code&gt;MAIRE&lt;/code&gt; (114 192 lignes) et &lt;code&gt;PREMIER ADJOINT AU MAIRE&lt;/code&gt; (37 511 lignes) et moins important dans les autres cas, qui&#xA;renvoient beaucoup moins de lignes.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;ajouter-des-jointures&#34;&gt;&#xA;  Ajouter des jointures&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#ajouter-des-jointures&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Maintenant que nous avons &lt;code&gt;MandateId&lt;/code&gt;, nous pouvons récupérer des clés&#xA;étrangères sur la ligne correspondante de la table &lt;code&gt;Mandate&lt;/code&gt;, puis effectuer des&#xA;jointures pour obtenir plus d&amp;rsquo;informations sur la personne qui a été élue et la&#xA;commune où l&amp;rsquo;élection a eu lieu. Commençons par la commune. La table &lt;code&gt;Area&lt;/code&gt;&#xA;contient des données sur différents niveaux géographiques, y compris les&#xA;communes. Avant de pouvoir nous renseigner sur la commune, nous devons obtenir&#xA;son identifiant dans la table &lt;code&gt;Mandate&lt;/code&gt;. Regardons d&amp;rsquo;abord le plan d&amp;rsquo;exécution&#xA;d&amp;rsquo;une requête qui fait cela, sans l&amp;rsquo;exécuter :&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;EXPLAIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;FunctionStartDate&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;AreaId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Function&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Mandate&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;WHERE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;FunctionType&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;MAIRE&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AND&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;MandateId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;MandateId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;ORDER&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;BY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;FunctionStartDate&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;FETCH&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FIRST&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;750&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ROWS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ONLY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;QUERY PLAN&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Limit  (cost=0.85..968.89 rows=750 width=36)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -&amp;gt;  Nested Loop  (cost=0.85..147087.20 rows=113957 width=36)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        -&amp;gt;  Index Only Scan using index_function on &amp;#34;Function&amp;#34; func&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            (cost=0.42..4664.34 rows=113957 width=8)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;              Index Cond: (&amp;#34;FunctionType&amp;#34; = &amp;#39;MAIRE&amp;#39;::text)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        -&amp;gt;  Index Scan using &amp;#34;pk_Mandat&amp;#34; on &amp;#34;Mandate&amp;#34; m&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            (cost=0.43..1.25 rows=1 width=36)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;              Index Cond: (&amp;#34;MandateId&amp;#34; = func.&amp;#34;MandateId&amp;#34;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;La base de données fait toujours un &lt;code&gt;Index Only Scan&lt;/code&gt; pour la table &lt;code&gt;Fonction&lt;/code&gt;,&#xA;mais elle fait un &lt;code&gt;Index Scan&lt;/code&gt; pour la table &lt;code&gt;Mandate&lt;/code&gt;, en utilisant l&amp;rsquo;index de&#xA;clé primaire de cette table. Cela veut dire qu&amp;rsquo;elle parcourt l&amp;rsquo;index jusqu&amp;rsquo;à ce&#xA;qu&amp;rsquo;elle trouve le &lt;code&gt;MandateId&lt;/code&gt; correspondant, puis récupère la ligne&#xA;correspondante de la table &lt;code&gt;Mandate&lt;/code&gt; pour obtenir l&amp;rsquo;&lt;code&gt;AreaId&lt;/code&gt;. Nous pouvons créer&#xA;un index qui contient &lt;code&gt;AreaId&lt;/code&gt; pour effectuer un parcours d&amp;rsquo;index seul :&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INDEX&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;index_mandate&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Mandate&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;MandateId&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;INCLUDE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;AreaId&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Voici le plan d&amp;rsquo;exécution qui en résulte :&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;QUERY PLAN&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Limit  (cost=0.85..505.54 rows=750 width=10)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -&amp;gt;  Nested Loop  (cost=0.85..76310.71 rows=113401 width=10)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        -&amp;gt;  Index Only Scan using index_function on &amp;#34;Function&amp;#34; func&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            (cost=0.42..4643.26 rows=113401 width=8)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;              Index Cond: (&amp;#34;FunctionType&amp;#34; = &amp;#39;MAIRE&amp;#39;::text)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        -&amp;gt;  Index Only Scan using index_mandate on &amp;#34;Mandate&amp;#34; m&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            (cost=0.43..0.63 rows=1 width=10)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;              Index Cond: (&amp;#34;MandateId&amp;#34; = func.&amp;#34;MandateId&amp;#34;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Il semble que le coût ait baissé. Faisons un test de performance, encore une&#xA;fois avec différentes valeurs pour &lt;code&gt;FunctionType&lt;/code&gt;, pour comparer l&amp;rsquo;index de clé&#xA;primaire à l&amp;rsquo;index couvrant. Dans les deux cas nous garderons notre index le&#xA;plus performant sur &lt;code&gt;Function&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;figure&gt;&lt;img src=&#34;https://benjamingeer.name/fr/post/bref/municipalities-fr.svg&#34;&#xA;    alt=&#34;un diagramme à barres représentant des résultats de tests&#34; width=&#34;100%&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;L&amp;rsquo;index couvrant ne fait pas une grande différence, mais semble toutefois utile.&lt;/p&gt;&#xA;&lt;p&gt;Maintenant que nous avons l&amp;rsquo;&lt;code&gt;AreaId&lt;/code&gt; de la commune, nous pouvons obtenir son nom&#xA;et son &lt;a href=&#34;https://www.insee.fr/fr/information/2560452&#34; target=&#34;_blank&#34;&gt;code géographique&lt;/a&gt; (qui&#xA;n&amp;rsquo;est pas la même chose que le code postal). Nous aimerions aussi avoir le nom&#xA;de la personne qui a été élue.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;FunctionStartDate&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;area&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;AreaCode&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;as&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;code_commune&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;area&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;AreaName&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;as&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;commune&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;indiv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;FirstName&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;indiv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;LastName&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Function&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;JOIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Mandate&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;MandateId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;MandateId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;JOIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Area&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;area&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;AreaId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;area&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;AreaId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;JOIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Individual&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;indiv&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;IndividualId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;indiv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;IndividualId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;WHERE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;FunctionType&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;MAIRE&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;ORDER&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;BY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;FunctionStartDate&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;FETCH&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FIRST&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ROWS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ONLY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Comme il y a plusieurs jointures, j&amp;rsquo;ai utilisé le mot-clé &lt;code&gt;JOIN&lt;/code&gt; pour que la&#xA;requête soit un peu plus facile à lire. (Cela ne change pas le plan&#xA;d&amp;rsquo;exécution.) Et comme la requête renvoie maintenant davantage de colonnes, j&amp;rsquo;ai&#xA;demandé moins de lignes, pour que les résultats du test de performance ne soient&#xA;pas dominés par le temps qu&amp;rsquo;il faut pour renvoyer les résultats de la requête.&lt;/p&gt;&#xA;&lt;p&gt;Pour la jointure entre &lt;code&gt;Mandate&lt;/code&gt; et &lt;code&gt;Individual&lt;/code&gt;, nous ajoutons &lt;code&gt;IndividualId&lt;/code&gt; à&#xA;notre index sur &lt;code&gt;Mandate&lt;/code&gt; :&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INDEX&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;index_mandate&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Mandate&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;MandateId&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;INCLUDE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;AreaId&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;IndividualId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Puis nous créons des index couvrants sur &lt;code&gt;Area&lt;/code&gt; et &lt;code&gt;Individual&lt;/code&gt; pour notre&#xA;requête :&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INDEX&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;index_area&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Area&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;AreaId&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;INCLUDE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;AreaCode&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;AreaName&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INDEX&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;index_indiv&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Individual&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;IndividualId&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;INCLUDE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;FirstName&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;LastName&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Cela donne le plan d&amp;rsquo;exécution suivant :&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;QUERY PLAN&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Limit  (cost=1.57..132.35 rows=100 width=38)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -&amp;gt;  Nested Loop  (cost=1.57..148131.29 rows=113274 width=38)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        -&amp;gt;  Nested Loop  (cost=1.15..96170.50 rows=113274 width=34)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;              -&amp;gt;  Nested Loop  (cost=0.85..82875.64 rows=113274 width=22)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    -&amp;gt;  Index Only Scan using index_function on &amp;#34;Function&amp;#34; func&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        (cost=0.42..4636.71 rows=113274 width=8)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                          Index Cond: (&amp;#34;FunctionType&amp;#34; = &amp;#39;MAIRE&amp;#39;::text)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    -&amp;gt;  Index Only Scan using index_mandate on &amp;#34;Mandate&amp;#34; m&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        (cost=0.43..0.69 rows=1 width=22)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                          Index Cond: (&amp;#34;MandateId&amp;#34; = func.&amp;#34;MandateId&amp;#34;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;              -&amp;gt;  Memoize  (cost=0.30..0.32 rows=1 width=24)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    Cache Key: m.&amp;#34;AreaId&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    Cache Mode: logical&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    -&amp;gt;  Index Only Scan using index_area on &amp;#34;Area&amp;#34; area&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        (cost=0.29..0.31 rows=1 width=24)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                          Index Cond: (&amp;#34;AreaId&amp;#34; = (m.&amp;#34;AreaId&amp;#34;)::text)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        -&amp;gt;  Index Only Scan using index_indiv on &amp;#34;Individual&amp;#34; indiv&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            (cost=0.42..0.46 rows=1 width=28)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;              Index Cond: (&amp;#34;IndividualId&amp;#34; = (m.&amp;#34;IndividualId&amp;#34;)::text)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Toutes les données viennent des index, les tables n&amp;rsquo;étant pas utilisés du tout.&#xA;Si nous ne créons pas les deux derniers index, il y a des &lt;code&gt;Index Scan&lt;/code&gt; plutôt&#xA;que des &lt;code&gt;Index Only Scan&lt;/code&gt; sur &lt;code&gt;Area&lt;/code&gt; et &lt;code&gt;Individual&lt;/code&gt;. Comparons la performance&#xA;de cette requête avec et sans ces deux index.&lt;/p&gt;&#xA;&lt;figure&gt;&lt;img src=&#34;https://benjamingeer.name/fr/post/bref/areas-individuals-fr.svg&#34;&#xA;    alt=&#34;un diagramme à barres représentant des résultats de tests&#34; width=&#34;100%&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;Il y a très peu de différence, mais garderons les index.&lt;/p&gt;&#xA;&lt;p&gt;Comparons maintenant la performance de cette dernière requête sans aucun index&#xA;(à part les index de clé primaire qui ont été créés par défaut) et avec tous les&#xA;index que nous avons créés :&lt;/p&gt;&#xA;&lt;figure&gt;&lt;img src=&#34;https://benjamingeer.name/fr/post/bref/all-indexes-fr.svg&#34;&#xA;    alt=&#34;un diagramme à barres représentant des résultats de tests&#34; width=&#34;100%&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;Cette requête est 14 à 24 fois plus rapide avec les index que sans eux.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;encore-plus-de-jointures&#34;&gt;&#xA;  Encore plus de jointures&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#encore-plus-de-jointures&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Essayons de récupérer le nom du département auquel la commune appartient. Nous&#xA;pouvons ajouter une jointure sur la table &lt;code&gt;Inclusion&lt;/code&gt; pour trouver l&amp;rsquo;&lt;code&gt;Area&lt;/code&gt; qui&#xA;représente le département :&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;EXPLAIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;FunctionStartDate&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;area1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;AreaCode&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;as&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;code_commune&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;area1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;AreaName&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;as&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;commune&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;area2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;AreaName&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;as&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;departement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;indiv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;FirstName&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;indiv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;LastName&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Function&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;JOIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Mandate&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;MandateId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;MandateId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;JOIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Area&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;area1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;AreaId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;area1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;AreaId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;JOIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Inclusion&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;incl&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;AreaId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;incl&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;IncludedAreaId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;JOIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Area&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;area2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;incl&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;IncludingAreaId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;area2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;AreaId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;JOIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Individual&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;indiv&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;IndividualId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;indiv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;IndividualId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;WHERE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;FunctionType&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;MAIRE&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;AND&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;area2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;AreaType&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Département&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;ORDER&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;BY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;FunctionStartDate&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;FETCH&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FIRST&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ROWS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ONLY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;42&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;43&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;44&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;45&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;46&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;QUERY PLAN&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Limit  (cost=35292.57..35304.24 rows=100 width=51)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -&amp;gt;  Gather Merge  (cost=35292.57..35351.14 rows=502 width=51)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        Workers Planned: 2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        -&amp;gt;  Sort  (cost=34292.55..34293.18 rows=251 width=51)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;              Sort Key: func.&amp;#34;FunctionStartDate&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;              -&amp;gt;  Nested Loop  (cost=30010.19..34282.96 rows=251 width=51)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    -&amp;gt;  Parallel Hash Join  (cost=30009.76..34167.82 rows=251 width=47)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                          Hash Cond: (func.&amp;#34;MandateId&amp;#34; = m.&amp;#34;MandateId&amp;#34;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                          -&amp;gt;  Parallel Index Only Scan using index_function on &amp;#34;Function&amp;#34; func&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                              (cost=0.42..3980.29 rows=47235 width=8)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                Index Cond: (&amp;#34;FunctionType&amp;#34; = &amp;#39;MAIRE&amp;#39;::text)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                          -&amp;gt;  Parallel Hash  (cost=29971.32..29971.32 rows=3042 width=47)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                -&amp;gt;  Hash Join  (cost=2914.37..29971.32 rows=3042 width=47)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                      Hash Cond: ((m.&amp;#34;AreaId&amp;#34;)::text = (area1.&amp;#34;AreaId&amp;#34;)::text)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                      -&amp;gt;  Parallel Seq Scan on &amp;#34;Mandate&amp;#34; m&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                          (cost=0.00..24881.12 rows=572112 width=22)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                      -&amp;gt;  Hash  (cost=2911.27..2911.27 rows=248 width=43)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                            -&amp;gt;  Nested Loop&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                (cost=967.16..2911.27 rows=248 width=43)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                  -&amp;gt;  Hash Join&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                      (cost=966.88..2832.29 rows=248 width=19)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                        Hash Cond:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                        ((incl.&amp;#34;IncludingAreaId&amp;#34;)::text =&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                         (area2.&amp;#34;AreaId&amp;#34;)::text)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                        -&amp;gt;  Seq Scan on &amp;#34;Inclusion&amp;#34; incl&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                            (cost=0.00..1607.70&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                             rows=98170 width=15)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                        -&amp;gt;  Hash&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                            (cost=965.40..965.40&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                             rows=118 width=19)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                              -&amp;gt;  Seq Scan on &amp;#34;Area&amp;#34; area2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                                  (cost=0.00..965.40&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                                   rows=118 width=19)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                                    Filter:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                                    ((&amp;#34;AreaType&amp;#34;)::text =&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                                    &amp;#39;Département&amp;#39;::text)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                  -&amp;gt;  Index Only Scan using index_area&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                      on &amp;#34;Area&amp;#34; area1&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                      (cost=0.29..0.32 rows=1 width=24)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                        Index Cond:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                        (&amp;#34;AreaId&amp;#34; =&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                         (incl.&amp;#34;IncludedAreaId&amp;#34;)::text)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    -&amp;gt;  Index Only Scan using index_indiv on &amp;#34;Individual&amp;#34; indiv&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        (cost=0.42..0.46 rows=1 width=28)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                          Index Cond: (&amp;#34;IndividualId&amp;#34; = (m.&amp;#34;IndividualId&amp;#34;)::text)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Qu&amp;rsquo;est-ce qui s&amp;rsquo;est passé ? Postgres a décidé qu&amp;rsquo;une jointure de hachage serait&#xA;plus efficace que l&amp;rsquo;ajout d&amp;rsquo;une autre boucle imbriquée. Plutôt que d&amp;rsquo;utiliser&#xA;notre index sur la table &lt;code&gt;Mandate&lt;/code&gt;, il compte lire environ 500 000 lignes et les&#xA;mettre dans une table de hachage en mémoire. Il utilise l&amp;rsquo;index trié par date&#xA;sur &lt;code&gt;Fonction&lt;/code&gt;, mais comme une table de hachage n&amp;rsquo;est pas triée, il doit ensuite&#xA;trier les résultats à nouveau. En utilisant &lt;code&gt;EXPLAIN ANALYZE&lt;/code&gt;, nous pouvons&#xA;constater que la requête prend à peu près 600 ms. Le simple fait d&amp;rsquo;obtenir le&#xA;nom du département a ralenti notre requête de plusieurs centaines de fois.&lt;/p&gt;&#xA;&lt;p&gt;Nous avons plusieurs options :&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Donner à l&amp;rsquo;optimiseur une meilleure option que la jointure de hachage.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Optimiser la jointure de hachage en demandant moins de colonnes (ce qui n&amp;rsquo;est&#xA;pas vraiment possible dans notre cas) ou moins de lignes (nous pourrions, par&#xA;exemple, ajouter une condition &lt;code&gt;WHERE&lt;/code&gt; comme &lt;code&gt;func.&amp;quot;FunctionStartDate&amp;quot; &amp;lt; DATE &#39;1975-01-01&#39;&lt;/code&gt;).&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Effectuer la jointure dans l&amp;rsquo;application. Dans le cas présent, comme il n&amp;rsquo;y a&#xA;que 101 départements en France et qu&amp;rsquo;ils changent très rarement,&#xA;l&amp;rsquo;application pourrait les lire au démarrage. Le code géographique de chaque&#xA;commune (que nous avons déjà obtenu avec la requête précédente) contient le code&#xA;du département. Il serait donc facile pour l&amp;rsquo;application de chercher le&#xA;département en mémoire.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;Essayons la première option. Nous pouvons ajouter cet index :&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INDEX&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;index_inclusion&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Inclusion&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;IncludedAreaId&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;INCLUDE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;IncludingAreaId&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Cela nous donne à nouveau un plan d&amp;rsquo;exécution à boucles imbriquées :&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;QUERY PLAN&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Limit  (cost=1002.32..10605.10 rows=100 width=51)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -&amp;gt;  Nested Loop  (cost=1002.32..58907.08 rows=603 width=51)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        -&amp;gt;  Gather Merge  (cost=1001.89..58630.47 rows=603 width=47)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;              Workers Planned: 2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;              -&amp;gt;  Nested Loop  (cost=1.87..57560.84 rows=251 width=47)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    -&amp;gt;  Nested Loop  (cost=1.58..57476.99 rows=272 width=41)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                          -&amp;gt;  Nested Loop  (cost=1.28..53851.27 rows=107699 width=37)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                -&amp;gt;  Nested Loop  (cost=0.85..36596.43 rows=47235 width=22)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                      -&amp;gt;  Parallel Index Only Scan using index_function&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                          on &amp;#34;Function&amp;#34; func&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                          (cost=0.42..3980.29 rows=47235 width=8)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                            Index Cond: (&amp;#34;FunctionType&amp;#34; = &amp;#39;MAIRE&amp;#39;::text)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                      -&amp;gt;  Index Only Scan using index_mandate on &amp;#34;Mandate&amp;#34; m&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                          (cost=0.43..0.69 rows=1 width=22)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                            Index Cond: (&amp;#34;MandateId&amp;#34; = func.&amp;#34;MandateId&amp;#34;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                -&amp;gt;  Memoize  (cost=0.43..0.46 rows=2 width=15)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                      Cache Key: m.&amp;#34;AreaId&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                      Cache Mode: logical&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                      -&amp;gt;  Index Only Scan using index_inclusion&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                          on &amp;#34;Inclusion&amp;#34; incl&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                          (cost=0.42..0.45 rows=2 width=15)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                            Index Cond: (&amp;#34;IncludedAreaId&amp;#34; = (m.&amp;#34;AreaId&amp;#34;)::text)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                          -&amp;gt;  Memoize  (cost=0.30..0.34 rows=1 width=19)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                Cache Key: incl.&amp;#34;IncludingAreaId&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                Cache Mode: logical&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                -&amp;gt;  Index Scan using &amp;#34;pk_Territoire&amp;#34; on &amp;#34;Area&amp;#34; area2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                    (cost=0.29..0.33 rows=1 width=19)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                      Index Cond:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                      ((&amp;#34;AreaId&amp;#34;)::text = (incl.&amp;#34;IncludingAreaId&amp;#34;)::text)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                      Filter: ((&amp;#34;AreaType&amp;#34;)::text = &amp;#39;Département&amp;#39;::text)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    -&amp;gt;  Index Only Scan using index_area on &amp;#34;Area&amp;#34; area1&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        (cost=0.29..0.31 rows=1 width=24)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                          Index Cond: (&amp;#34;AreaId&amp;#34; = (m.&amp;#34;AreaId&amp;#34;)::text)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        -&amp;gt;  Index Only Scan using index_indiv on &amp;#34;Individual&amp;#34; indiv&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            (cost=0.42..0.46 rows=1 width=28)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;              Index Cond: (&amp;#34;IndividualId&amp;#34; = (m.&amp;#34;IndividualId&amp;#34;)::text)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Le coût reste pourtant assez élevé, et &lt;code&gt;EXPLAIN ANALYZE&lt;/code&gt; indique que la requête&#xA;prend 12 ms environ. Un test de performance indique qu&amp;rsquo;elle peut être 10 à 20&#xA;fois plus lente que notre requête précédente :&lt;/p&gt;&#xA;&lt;figure&gt;&lt;img src=&#34;https://benjamingeer.name/fr/post/bref/departments-fr.svg&#34;&#xA;    alt=&#34;un diagramme à barres représentant des résultats de tests&#34; width=&#34;100%&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;Il serait plus efficace de garder la requête précédente et d&amp;rsquo;effectuer la&#xA;jointure dans l&amp;rsquo;application.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;conclusion&#34;&gt;&#xA;  Conclusion&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#conclusion&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Cette exercice a démontré quelques points importants sur l&amp;rsquo;optimisation des&#xA;bases de données :&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;À chaque fois que nous modifions une requête, il faut revérifier le plan&#xA;d&amp;rsquo;exécution pour connaître l&amp;rsquo;effet de la modification sur les performances.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Des requêtes différentes peuvent avoir besoin d&amp;rsquo;index différents.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Un parcours d&amp;rsquo;index seul peut être le meilleur moyen d&amp;rsquo;améliorer la&#xA;performance d&amp;rsquo;une requête dans certains cas, mais il faut vérifier cette&#xA;hypothèse en la testant.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Parfois la meilleure optimisation est de demander moins de données.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Tous les scripts et les fichiers de configuration que j&amp;rsquo;ai utilisés pour cet&#xA;exercice se trouvent dans &lt;a href=&#34;https://codeberg.org/benjamingeer/BREF_optimisation&#34; target=&#34;_blank&#34;&gt;ce dépôt&#xA;git&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Pour en savoir plus sur ce sujet, je recommande le site web &lt;a href=&#34;https://use-the-index-luke.com/fr&#34; target=&#34;_blank&#34;&gt;Use the Index,&#xA;Luke!&lt;/a&gt; de Markus Winand, ainsi que son livre&#xA;&lt;a href=&#34;https://sql-au-coeur-des-performances.fr&#34; target=&#34;_blank&#34;&gt;SQL : Au cœur des performances&lt;/a&gt;.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Comparer les performances de requêtes SQL</title>
      <link>https://benjamingeer.name/fr/post/sqlstopwatch/</link>
      <pubDate>Thu, 29 Jan 2026 18:25:18 +0100</pubDate>
      <guid>https://benjamingeer.name/fr/post/sqlstopwatch/</guid>
      <description>&lt;p&gt;J&amp;rsquo;ai réalisé un petit programme en Rust,&#xA;&lt;a href=&#34;https://codeberg.org/benjamingeer/sqlstopwatch&#34; target=&#34;_blank&#34;&gt;sqlstopwatch&lt;/a&gt;, pour comparer&#xA;les performances de différentes requêtes&#xA;&lt;a href=&#34;https://fr.wikipedia.org/wiki/Structured_Query_Language&#34; target=&#34;_blank&#34;&gt;SQL&lt;/a&gt;. J&amp;rsquo;ai été&#xA;inspiré par l&amp;rsquo;article &lt;a href=&#34;https://www.jooq.org/benchmark&#34; target=&#34;_blank&#34;&gt;Benchmarking&#xA;SQL&lt;/a&gt; publié par le projet jOOQ, dans lequel le&#xA;code du test est implémenté en SQL. Je voulais quelque chose de semblable,&#xA;mais j&amp;rsquo;avais quelques exigences supplémentaires :&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Un programme en ligne de commande avec une interface utilisateur simple en&#xA;mode texte (TUI) qui affiche une barre de progression.&lt;/li&gt;&#xA;&lt;li&gt;Le programme devrait prendre en charge&#xA;&lt;a href=&#34;https://www.postgresql.org&#34; target=&#34;_blank&#34;&gt;PostgreSQL&lt;/a&gt;, &lt;a href=&#34;https://www.mysql.com&#34; target=&#34;_blank&#34;&gt;MySQL&lt;/a&gt; et&#xA;&lt;a href=&#34;https://sqlite.org&#34; target=&#34;_blank&#34;&gt;SQLite&lt;/a&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Il devrait lire les requêtes SQL et les paramètres du test dans un fichier de&#xA;configuration indiqué sur la ligne de commande.&lt;/li&gt;&#xA;&lt;li&gt;Il devrait afficher les résultats sous forme de table dans le terminal ou les&#xA;enregistrer dans un fichier au format CSV que je puisse utiliser pour générer un&#xA;diagramme.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;L&amp;rsquo;interface utilisateur a été facile à réaliser avec&#xA;&lt;a href=&#34;https://ratatui.rs&#34; target=&#34;_blank&#34;&gt;Ratatui&lt;/a&gt;. Pour interagir avec la base de données, j&amp;rsquo;ai&#xA;utilisé la bibliothèque asynchrone &lt;a href=&#34;https://crates.io/crates/sqlx&#34; target=&#34;_blank&#34;&gt;sqlx&lt;/a&gt;, qui&#xA;fournit une bibliothèque SQLite embarquée.&lt;/p&gt;&#xA;&lt;p&gt;J&amp;rsquo;ai pensé à utiliser le format &lt;a href=&#34;https://toml.io&#34; target=&#34;_blank&#34;&gt;TOML&lt;/a&gt; pour le fichier de&#xA;configuration, mais le fichier doit fournir les identifiants de connexion. Dans&#xA;les environnements de test, il se peut que les identifiants doivent être chargés&#xA;à partir de variables d&amp;rsquo;environnement ou de fichiers sur un système de fichiers&#xA;monté, mais TOML ne permet pas d&amp;rsquo;effectuer de telles opérations. En plus, on&#xA;pourrait vouloir générer plusieurs requêtes similaires pour les comparer, comme&#xA;je l&amp;rsquo;ai fait dans &lt;a href=&#34;https://benjamingeer.name/fr/post/bref&#34;&gt;ce projet d&amp;rsquo;optimisation de base de&#xA;données&lt;/a&gt;. Par conséquent, il vaut mieux que le fichier de&#xA;configuration soit un programme dans un langage de script. Mon &lt;a href=&#34;https://benjamingeer.name/fr/post/organiclox&#34;&gt;exercice&#xA;d&amp;rsquo;implémentation d&amp;rsquo;un interpréteur de langage de script&lt;/a&gt;&#xA;m&amp;rsquo;avait permis d&amp;rsquo;apprécier à sa juste valeur la machine virtuelle&#xA;&lt;a href=&#34;https://www.lua.org&#34; target=&#34;_blank&#34;&gt;Lua&lt;/a&gt;. Le fichier de configuration est donc un script en&#xA;Lua, que je trouve plus commode de rédiger en&#xA;&lt;a href=&#34;https://fennel-lang.org&#34; target=&#34;_blank&#34;&gt;Fennel&lt;/a&gt;, un dialect de Lisp qui se compile en Lua.&#xA;Grâce à la bibliothèque &lt;a href=&#34;https://crates.io/crates/mlua&#34; target=&#34;_blank&#34;&gt;mlua&lt;/a&gt;, il a été très&#xA;facile d&amp;rsquo;embarquer un interpréteur Lua dans le programme et d&amp;rsquo;utiliser&#xA;&lt;a href=&#34;https://serde.rs&#34; target=&#34;_blank&#34;&gt;Serde&lt;/a&gt; pour convertir des tables Lua en &lt;code&gt;struct&lt;/code&gt;s Rust.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Créer un client Bittorrent en Rust</title>
      <link>https://benjamingeer.name/fr/post/sayaca/</link>
      <pubDate>Thu, 15 Jan 2026 15:16:01 +0100</pubDate>
      <guid>https://benjamingeer.name/fr/post/sayaca/</guid>
      <description>&lt;h2 class=&#34;heading&#34; id=&#34;aperçu&#34;&gt;&#xA;  Aperçu&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#aper%c3%a7u&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Pour mon deuxième exercice d&amp;rsquo;apprentissage de Rust (après&#xA;&lt;a href=&#34;https://benjamingeer.name/fr/post/organiclox&#34;&gt;OrganicLox&lt;/a&gt;), j&amp;rsquo;ai décidé de réaliser un client pour&#xA;&lt;a href=&#34;https://en.wikipedia.org/wiki/BitTorrent&#34; target=&#34;_blank&#34;&gt;Bittorrent&lt;/a&gt;, le protocole de&#xA;transfert de données pair-à-pair. Les clients Bittorrent que j&amp;rsquo;ai utilisés ont&#xA;des interfaces graphiques complexes qui semblent destinées aux gens qui&#xA;téléchargent des torrents à longueur de journée, plutôt que pour l&amp;rsquo;utilisateur&#xA;occasionnel comme moi, qui veut tout simplement obtenir un seul fichier. Et&#xA;comme beaucoup d&amp;rsquo;applications à interface graphique, les clients Bittorrent ont&#xA;tendance à accumuler des fichiers qui occupent de l&amp;rsquo;espace disque dans des&#xA;répertoires obscurs. Je fais beaucoup de choses dans le terminal et quand j&amp;rsquo;ai&#xA;besoin de télécharger un fichier, mon réflexe est d&amp;rsquo;utiliser&#xA;&lt;a href=&#34;https://curl.se/&#34; target=&#34;_blank&#34;&gt;curl&lt;/a&gt;. Je me suis donc dit, pourquoi ne pas créer quelque&#xA;chose comme curl pour Bittorrent ? En pensant à &lt;a href=&#34;https://curl.se/docs/tutorial.html#:~:text=www.example.com-,Progress%20Meter,-The%20progress%20meter&#34; target=&#34;_blank&#34;&gt;l&amp;rsquo;indicateur de&#xA;progression&lt;/a&gt;&#xA;de curl, l&amp;rsquo;idée m&amp;rsquo;est venue à l&amp;rsquo;esprit de faire quelque chose de semblable avec&#xA;&lt;a href=&#34;https://ratatui.rs&#34; target=&#34;_blank&#34;&gt;Ratatui&lt;/a&gt;, une bibliothèque de création d&amp;rsquo;environnements&#xA;en mode texte (TUI), que je voulais de toute façon essayer.&lt;/p&gt;&#xA;&lt;p&gt;La réalisation d&amp;rsquo;un client Bittorrent semblait être une bonne occasion&#xA;d&amp;rsquo;apprendre la programmation asynchrone en Rust. J&amp;rsquo;avais lu beaucoup de&#xA;critiques d&amp;rsquo;&lt;code&gt;async&lt;/code&gt; en Rust, mais je l&amp;rsquo;ai trouvé agréable à utiliser (en&#xA;utilisant la bibliothèque &lt;a href=&#34;https://tokio.rs&#34; target=&#34;_blank&#34;&gt;Tokio&lt;/a&gt;) et certainement plus&#xA;confortable que les infrastructures logicielles comparables que j&amp;rsquo;avais&#xA;utilisées en Scala (&lt;a href=&#34;https://akka.io&#34; target=&#34;_blank&#34;&gt;Akka&lt;/a&gt; et &lt;a href=&#34;https://typelevel.org/cats-effect/&#34; target=&#34;_blank&#34;&gt;Cats&#xA;Effect&lt;/a&gt;). J&amp;rsquo;aime particulièrement le fait&#xA;qu&amp;rsquo;une fonction &lt;code&gt;async&lt;/code&gt; peut être exécutée dans une tâche existante ou dans sa&#xA;propre tâche, à la différence du &lt;code&gt;Future&lt;/code&gt; de Scala, qui est affecté à un fil&#xA;d&amp;rsquo;exécution et se lance dès sa construction. L&amp;rsquo;approche de Rust semble mieux&#xA;adapté au remaniement et à la maintenabilité. En même temps, je suis content de&#xA;ne pas avoir à gérer la complexité liée à l&amp;rsquo;utilisation des monades comme dans&#xA;Cats Effect.&lt;/p&gt;&#xA;&lt;p&gt;Le résultat est &lt;a href=&#34;https://codeberg.org/benjamingeer/sayaca&#34; target=&#34;_blank&#34;&gt;Sayaca&lt;/a&gt;, qui porte&#xA;le nom d&amp;rsquo;un oiseau sud-américain qui joue un rôle important dans la dispersion&#xA;des graines (le verbe anglais &lt;em&gt;to seed&lt;/em&gt; veut dire ensemencer, et dans la&#xA;terminologie de Bittorrent, envoyer des données aux autres pairs).&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;la-conception&#34;&gt;&#xA;  La conception&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#la-conception&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Ma première tâche a été de réaliser un analyseur syntaxique pour&#xA;&lt;a href=&#34;https://en.wikipedia.org/wiki/Bencode&#34; target=&#34;_blank&#34;&gt;Bencode&lt;/a&gt;, le format de données&#xA;utilisées dans le protocole Bittorrent. Au niveau conceptuel, Bencode ressemble&#xA;à &lt;a href=&#34;https://en.wikipedia.org/wiki/JSON&#34; target=&#34;_blank&#34;&gt;JSON&lt;/a&gt;, mais il est destiné à la&#xA;représentation de données binaires plutôt que textuelles. J&amp;rsquo;avais envie&#xA;d&amp;rsquo;essayer d&amp;rsquo;utiliser une bibliothèque de combinateurs d&amp;rsquo;analyseurs syntaxiques,&#xA;et je n&amp;rsquo;ai pas eu de mal à implémenter l&amp;rsquo;analyseur en utilisant&#xA;&lt;a href=&#34;https://github.com/rust-bakery/nom&#34; target=&#34;_blank&#34;&gt;nom&lt;/a&gt;. Comme je voulais être en mesure de&#xA;sérialiser et de désérialiser des &lt;code&gt;struct&lt;/code&gt;s en Rust au format Bencode, j&amp;rsquo;ai&#xA;ajouté la prise en charge de la bibliothèque &lt;a href=&#34;https://serde.rs&#34; target=&#34;_blank&#34;&gt;Serde&lt;/a&gt;. J&amp;rsquo;ai&#xA;publié la crate issue de ce travail sous le nom de&#xA;&lt;a href=&#34;https://crates.io/crates/bside&#34; target=&#34;_blank&#34;&gt;bside&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;La principale difficulté dans la conception du client résidait dans le caractère&#xA;confus des spécifications Bittorrent. Il y a des ambigüités (le mot &lt;em&gt;piece&lt;/em&gt; a&#xA;deux sens différents) et les implémentations se sont écartées des spécifications&#xA;(par exemple, les identifiants de pair ne sont pas utilisés pour identifier&#xA;les pairs). Une grande partie des informations relatives au protocole ne figure&#xA;pas dans les spécifications officielles, mais dans d&amp;rsquo;autres documents dispersés&#xA;sur le Web. Il y a une &lt;a href=&#34;https://www.bittorrent.org/beps/bep_0000.html&#34; target=&#34;_blank&#34;&gt;longue&#xA;liste&lt;/a&gt; (non mise à jour depuis&#xA;2018) de projets d&amp;rsquo;extension du protocole qui sont pris en charge par de&#xA;nombreux clients. Une extension dite &lt;a href=&#34;https://en.wikipedia.org/wiki/BitTorrent_protocol_encryption&#34; target=&#34;_blank&#34;&gt;de&#xA;chiffrement&lt;/a&gt;&#xA;(qui semble en réalité décrire une forme de brouillage) semble être largement&#xA;mise en œuvre, mais d&amp;rsquo;après ce que je peux en juger, depuis 2023, &lt;a href=&#34;https://web.archive.org/web/20230405235517/http://wiki.vuze.com/w/Message_Stream_Encryption&#34; target=&#34;_blank&#34;&gt;sa&#xA;spécification&lt;/a&gt;&#xA;n&amp;rsquo;est conservée que dans la Wayback Machine de l&amp;rsquo;Internet Archive. Il existe un&#xA;&lt;a href=&#34;https://bittorrent.org/beps/bep_0052.html&#34; target=&#34;_blank&#34;&gt;projet de spécification du protocole BitTorrent&#xA;v2&lt;/a&gt; (non mis à jour depuis 2017) qui&#xA;tente de corriger certains défauts du protocole d&amp;rsquo;origine, comme sa dépendance&#xA;vis-à-vis de la fonction de hachage&#xA;&lt;a href=&#34;https://en.wikipedia.org/wiki/SHA-1&#34; target=&#34;_blank&#34;&gt;SHA-1&lt;/a&gt; (qui n&amp;rsquo;est plus considérée comme&#xA;sécurisée depuis 2005). J&amp;rsquo;aurais pu errer longtemps dans un dédale de documents&#xA;et dans le code source des clients existants. Pour simplifier les choses, j&amp;rsquo;ai&#xA;décidé de ne mettre en œuvre que le &lt;a href=&#34;https://bittorrent.org/beps/bep_0003.html&#34; target=&#34;_blank&#34;&gt;protocole&#xA;d&amp;rsquo;origine&lt;/a&gt; et l&amp;rsquo;extension &lt;a href=&#34;https://www.bittorrent.org/beps/bep_0007.html&#34; target=&#34;_blank&#34;&gt;IPv6&#xA;tracker&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Quand un client Bittorrent enregistre des données sur le disque, il devrait&#xA;offrir de bonnes performances avec des fichiers volumineux, être capable&#xA;d&amp;rsquo;interrompre un téléchargement et de le reprendre plus tard (ce qui signifie&#xA;qu&amp;rsquo;il doit noter quels fragments ont été téléchargées) et gérer les torrents qui&#xA;comprennent plusieurs fichiers. Pour faire tout cela, et pour que les choses&#xA;soient claires pour l&amp;rsquo;utilisateur, j&amp;rsquo;ai choisi d&amp;rsquo;enregistrer les données&#xA;téléchargées dans un fichier intermédiaire (avec l&amp;rsquo;extension &lt;code&gt;.sayaca&lt;/code&gt;), dans le&#xA;même répertoire où les fichiers finaux seront enregistrés. Le fichier&#xA;intermédiaire contient un champ de bits indiquant les fragments qui ont été&#xA;téléchargés (il s&amp;rsquo;agit du même champ de bits qu&amp;rsquo;il faut de toute façon envoyer&#xA;aux pairs). Pour lire et écrire ce fichier, Sayaca utilise la projection en&#xA;mémoire, ce qui devrait offrir de bonnes performances d&amp;rsquo;entrée-sortie avec des&#xA;fichiers volumineux. Une fois le téléchargement terminé, il copie les données&#xA;depuis le fichier intermédiaire vers les fichiers finaux. Lorsque le programme&#xA;se ferme, le fichier intermédiaire est supprimé s&amp;rsquo;il n&amp;rsquo;est plus nécessaire.&lt;/p&gt;&#xA;&lt;p&gt;Comme un client Bittorrent est tributaire des entrées-sorties (&lt;em&gt;I/O bound&lt;/em&gt;),&#xA;j&amp;rsquo;ai décidé d&amp;rsquo;employer &lt;a href=&#34;https://codeberg.org/benjamingeer/sayaca/src/branch/main/docs/design.md&#34; target=&#34;_blank&#34;&gt;une architecture&#xA;événementielle&lt;/a&gt;&#xA;dans laquelle une seule tâche accomplit la majeure partie du travail, comme dans&#xA;&lt;a href=&#34;https://redis.io&#34; target=&#34;_blank&#34;&gt;Redis&lt;/a&gt;. Cette tâche principale délègue toute les&#xA;entrées-sorties réseau à d&amp;rsquo;autres tâches, avec lesquelles elle communique via&#xA;des &lt;a href=&#34;https://docs.rs/tokio/latest/tokio/sync/&#34; target=&#34;_blank&#34;&gt;canaux&lt;/a&gt;. Cela a été très simple à&#xA;mettre en œuvre et a eu l&amp;rsquo;avantage de rendre facile la création de tests&#xA;unitaires pour la tâche principale.&lt;/p&gt;&#xA;&lt;p&gt;Une grande partie du travail effectué par un client Bittorrent revient à tenir&#xA;une sorte de comptabilité. Dans Sayaca, ce travail est la responsabilité du&#xA;&lt;a href=&#34;https://codeberg.org/benjamingeer/sayaca/src/branch/main/src/client/bookkeeper.rs&#34; target=&#34;_blank&#34;&gt;&lt;code&gt;Bookkeeper&lt;/code&gt;&lt;/a&gt;&#xA;(« comptable »). Par exemple, dans &lt;a href=&#34;https://wiki.theory.org/BitTorrentSpecification#Piece_downloading_strategy&#34; target=&#34;_blank&#34;&gt;l&amp;rsquo;algorithme&#xA;recommandé&lt;/a&gt;&#xA;de sélection des fragments à demander aux pairs, le client essaie de demander&#xA;d&amp;rsquo;abord les fragments les plus rares. Cela nécessite une structure de données&#xA;qui note les fragments dont dispose chaque pair, ainsi que la rareté de chaque&#xA;fragment, entre autres. Il y a plusieurs façons de réaliser cela et j&amp;rsquo;ai décidé&#xA;d&amp;rsquo;utiliser un &lt;a href=&#34;https://doc.rust-lang.org/std/collections/struct.BTreeMap.html&#34; target=&#34;_blank&#34;&gt;tableau associatif&#xA;ordonné&lt;/a&gt;, trié&#xA;par ordre de rareté, pour stocker les identificateurs de fragments et les&#xA;ensembles de pairs qui les possèdent. Le &lt;code&gt;Bookkeeper&lt;/code&gt; peut ainsi trouver&#xA;facilement un fragment, choisi au hasard parmi les plus rares, associé à un pair&#xA;choisi au hasard parmi ceux qui possèdent ce fragment et qui nous ont autorisé à&#xA;leur envoyer des demandes. Ainsi une grande partie du travail du client consiste&#xA;à mettre à jour le &lt;code&gt;Bookkeper&lt;/code&gt; lors de la réception de nouvelles informations et&#xA;à l&amp;rsquo;interroger pour savoir ce qu&amp;rsquo;il faut faire ensuite.&lt;/p&gt;&#xA;&lt;p&gt;J&amp;rsquo;aime bien les TUI et il a été facile de créer un TUI simple avec Ratatui. Mais&#xA;comme le client est une bibliothèque qui communique avec son interface&#xA;utilisateur via des canaux, il serait simple d&amp;rsquo;intégrer le client dans une autre&#xA;interface utilisateur, comme une interface en ligne de commande &lt;a href=&#34;https://xogium.me/the-text-mode-lie-why-modern-tuis-are-a-nightmare-for-accessibility&#34; target=&#34;_blank&#34;&gt;plus&#xA;accessible&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;dautres-approches-possibles&#34;&gt;&#xA;  D&amp;rsquo;autres approches possibles&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#dautres-approches-possibles&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;J&amp;rsquo;ai choisi d&amp;rsquo;utiliser Tokio parce que je voulais en savoir plus à son sujet et&#xA;sur &lt;code&gt;async&lt;/code&gt;, mais je pense que le programme n&amp;rsquo;aurait probablement pas été très&#xA;différent si j&amp;rsquo;avais utilisé des fils d&amp;rsquo;exécution à la place, avec la même&#xA;communication via des canaux.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Mona Ja‘bub, Conduire la société vers le changement</title>
      <link>https://benjamingeer.name/fr/post/jabub-dhofar/</link>
      <pubDate>Wed, 03 Dec 2025 00:00:00 +0000</pubDate>
      <guid>https://benjamingeer.name/fr/post/jabub-dhofar/</guid>
      <description>&lt;p&gt;[Version française du texte publié en espagnol.&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;]&lt;/p&gt;&#xA;&lt;p&gt;Mona Salem Said Ja‘bub, قيادة المجتمع نحو التغيير: التجربة التربوية لثورة ظفار&#xA;(1969-1992) [&lt;em&gt;Conduire la société vers le changement : l&amp;rsquo;expérience éducative&#xA;de la révolution du Dhofar (1969-1992)&lt;/em&gt;], Beyrouth : مركز دراسات الوحدة العربية&#xA;[Centre d&amp;rsquo;études de l&amp;rsquo;unité arabe], première édition 2010, deuxième édition&#xA;2023, 368 pages.&lt;/p&gt;&#xA;&lt;p&gt;Ce premier livre de Mona Ja‘bub, historienne omanaise, a été salué dans le monde&#xA;arabe pour son approche de l&amp;rsquo;histoire sociale et culturelle de la révolution du&#xA;Dhofar en Oman. Publié par une maison d&amp;rsquo;édition arabe prestigieuse spécialisée&#xA;dans les sciences sociales, le livre a d&amp;rsquo;abord été retiré par les autorités&#xA;omanaises du Salon international du livre de Mascate en 2012, puis remis en&#xA;vente le lendemain, signe d&amp;rsquo;un assouplissement de la censure. Il se concentre&#xA;sur des questions de genre et de circulation des idées et, en se penchant sur&#xA;des événements historiques peu connus en dehors du monde arabe, apporte une&#xA;contribution originale à l&amp;rsquo;étude de la réception mondiale du maoïsme et du&#xA;marxisme dans les années 1960 et 1970.&lt;/p&gt;&#xA;&lt;p&gt;De 1968 à 1975, la province du Dhofar du Sultanat d&amp;rsquo;Oman a connu une révolution&#xA;marxiste-léniniste contre le sultan Saïd et son successeur Qaboos, qui&#xA;dépendaient de l&amp;rsquo;empire britannique. À l&amp;rsquo;époque, le Dhofar avait une économie de&#xA;subsistance et sa population vivait dans une pauvreté extrême. Sur la côte il y&#xA;avait des pêcheurs, sur la plaine il y avait un peu d&amp;rsquo;agriculture et surtout des&#xA;arbres à encens, et dans les hautes terres on élevait du bétail. Même après le&#xA;commencement de l&amp;rsquo;exportation du pétrole en 1967, l&amp;rsquo;État percevait des impôts&#xA;sans fournir de services à la population : la médecine moderne était inconnue,&#xA;la seule école était réservée à la cour du sultan et au Dhofar la majeure partie&#xA;de la population et la quasi totalité des femmes étaient analphabètes. Dans le&#xA;système tribal dhofari, les terres appartenaient à des tribus, non pas à des&#xA;individus, et certaines tribus avaient plus de prestige que d&amp;rsquo;autres et&#xA;portaient des armes. En bas de l&amp;rsquo;échelle sociale il y avaient des personnes&#xA;réduites en esclavage par les tribus et par le sultan.&lt;/p&gt;&#xA;&lt;p&gt;Une rébellion armée dhofarie d&amp;rsquo;inspiration panarabiste, lancée en 1965 par des&#xA;Dhofaris vivant au Koweït et soutenue par l&amp;rsquo;Égypte de Nasser, a été discréditée&#xA;par la défaite de l&amp;rsquo;Égypte et de ses alliés dans la guerre de juin 1967 contre&#xA;Israël. Quelques mois plus tard, des militants dhofaris se sont rendus en Chine&#xA;pour être formés à la révolution. Ils sont retournés chez eux convaincus par le&#xA;maoïsme, sur un bateau chargé d&amp;rsquo;armes et de nourriture. Tout cela a permis aux&#xA;communistes dhofaris de prendre la direction de qui s&amp;rsquo;appelait désormais le&#xA;Front populaire pour la libération d&amp;rsquo;Oman et du Golfe arabe (comme il a changé&#xA;de nom plusieurs fois, je l&amp;rsquo;appellerai simplement Front populaire). Ce virage à&#xA;gauche a été renforcé par le soutien indéfectible apporté à la révolution&#xA;dhofarie par le Yémen du Sud, voisin de l&amp;rsquo;Oman, qui est devenu, en 1970, le seul&#xA;pays communiste du monde arabe.&lt;/p&gt;&#xA;&lt;p&gt;L&amp;rsquo;application de la théorie marxiste au contexte local était pourtant&#xA;controversée. Quand le Front populaire a commandé un rapport à un marxiste de&#xA;Bahreïn sur la structure des classes sociales au Dhofar, le rapport a conclu&#xA;qu&amp;rsquo;il n&amp;rsquo;y avait pas de classes au Dhofar, mais seulement des tribus. Cette&#xA;conclusion a déplu aux cadres du Front populaire et le rapport n&amp;rsquo;a pas été&#xA;publié. Ils reconnaissaient qu&amp;rsquo;il n&amp;rsquo;y avait ni prolétariat ni bourgeoisie au&#xA;Dhofar, mais affirmaient que les tribus étaient en réalité des classes.&lt;/p&gt;&#xA;&lt;p&gt;Le Front populaire a interdit l&amp;rsquo;esclavage dans le territoire libéré. Il a aboli&#xA;la propriété tribale, toutes les terres devenant des biens publics. Sous&#xA;l&amp;rsquo;impulsion de militantes féministes dans ses rangs, il a fait de la libération&#xA;des femmes un des piliers de sa doctrine. Les femmes ont donc porté des armes&#xA;dans l&amp;rsquo;armée révolutionnaire, l&amp;rsquo;alphabétisation des femmes a été une priorité et&#xA;la polygamie a été abolie.&lt;/p&gt;&#xA;&lt;p&gt;Mais les militants considéraient que la transformation sociale qu&amp;rsquo;ils&#xA;souhaitaient nécessitait non seulement des décrets imposés par la force, mais&#xA;aussi un système d&amp;rsquo;enseignement capable d&amp;rsquo;amener ses élèves à adopter des&#xA;valeurs et des comportements qui allaient à l&amp;rsquo;encontre des traditions. D&amp;rsquo;autres&#xA;chercheurs se sont penchés sur les aspects politiques de la révolution dhofarie,&#xA;mais l&amp;rsquo;originalité du livre de Mona Ja‘bub est qu&amp;rsquo;il se concentre sur l&amp;rsquo;activité&#xA;éducative du Front populaire et surtout sur l&amp;rsquo;école et le collège qu&amp;rsquo;il a&#xA;établis au Yémen, près de la frontière omanaise. Ja‘bub a pu réaliser des&#xA;entretiens avec de nombreux anciens militants et anciens élèves de ces&#xA;établissements, ce qui lui a permis de dresser un portrait intime de cette&#xA;tentative d&amp;rsquo;adapter la théorie marxiste à un contexte très différent de&#xA;l&amp;rsquo;économie industrielle que Marx avait à l&amp;rsquo;esprit.&lt;/p&gt;&#xA;&lt;p&gt;L&amp;rsquo;appartenance des dhofaris à la nation arabe restait fondamentale dans&#xA;l&amp;rsquo;idéologie du Front populaire. La langue arabe standard, qu&amp;rsquo;ils considéraient&#xA;comme la langue nationale des arabes, occupait donc une place centrale dans la&#xA;culture que les enseignants révolutionnaires voulaient inculquer à leurs élèves.&#xA;Dans le monde arabe, de nombreux dialectes arabes, dont certains sont&#xA;mutuellement inintelligibles, sont utilisés dans la vie quotidienne, alors que&#xA;l&amp;rsquo;arabe standard, que peu de gens savent parler, est réservé principalement à&#xA;l&amp;rsquo;écrit et aux discours soutenus. Cependant, au Dhofar, la langue de la vie&#xA;quotidienne n&amp;rsquo;était pas arabe du tout : c&amp;rsquo;était le Shehri, un cousin éloigné de&#xA;l&amp;rsquo;arabe. Non seulement les élèves ne comprenaient pas l&amp;rsquo;arabe standard, ils ne&#xA;comprenaient aucun dialecte arabe. Dans un premier temps, les enseignants ont&#xA;fait face à cette situation en obligeant les élèves à parler toujours en arabe&#xA;standard (ce qui aurait été considéré comme bizarre dans tous les autres pays&#xA;arabes) et en leur interdisant de parler en Shehri, même en dehors des cours,&#xA;sous peine d&amp;rsquo;être punis. Si les élèves avaient besoin d&amp;rsquo;un mot qu&amp;rsquo;ils ne&#xA;connaissaient pas en arabe, ils ne pouvaient avoir recours qu&amp;rsquo;à des gestes. Les&#xA;enseignants ont affirmé aux élèves que cela faisait partie de leur devoir envers&#xA;leur patrie arabe. Ja‘bub nous montre que les élèves n&amp;rsquo;ont pas seulement obéi à&#xA;de telles règles par peur : ils les ont vraiment intériorisées. Une ancienne&#xA;élève se rappelle qu&amp;rsquo;un jour à la cantine scolaire, en parlant au cuisinier,&#xA;elle a laissé échapper un mot en Shehri et en a tout de suite eu honte. Elle&#xA;s&amp;rsquo;est dénoncée elle-même à la direction et ne s&amp;rsquo;est sentie soulagée qu&amp;rsquo;après&#xA;s&amp;rsquo;être excusée devant tous les autres élèves. Plus tard, un nouveau directeur a&#xA;abrogé l&amp;rsquo;interdiction du Shehri et a mis en place une politique de valorisation&#xA;de la culture dhofarie.&lt;/p&gt;&#xA;&lt;p&gt;Les établissements scolaires du Front populaire manquaient cruellement de moyens&#xA;pendant les premières années de leur existence. Au début, il n&amp;rsquo;y avait pas de&#xA;bâtiments, seulement des tentes. Faute de manuels scolaires, les élèves&#xA;copiaient leurs cours à la main. Pendant quatre ans, le seul livre disponible en&#xA;quantité suffisante pour l&amp;rsquo;enseignement de la lecture et de l&amp;rsquo;écriture en arabe&#xA;était une traduction du Petit livre rouge de Mao Tse-Toung, dont la Chine&#xA;envoyait un grand nombre d&amp;rsquo;exemplaires avec chaque livraison d&amp;rsquo;armes. C&amp;rsquo;était&#xA;aussi le manuel d&amp;rsquo;instruction politique le plus important du Front, à côté de&#xA;textes de Marx, d&amp;rsquo;Engels, de Lénine, de Staline, de Ho Chi Minh et de Che&#xA;Guevara. Mao était de loin la figure la plus admirée par la population dhofarie&#xA;et beaucoup de gens portaient des badges de Mao, non seulement, selon l&amp;rsquo;autrice,&#xA;parce qu&amp;rsquo;il leur envoyait des armes et de la nourriture, mais aussi parce que&#xA;ses idées correspondaient à leurs préoccupations, qu&amp;rsquo;il avait une conception&#xA;bien développée de la lutte anticoloniale et qu&amp;rsquo;il écrivait pour un public de&#xA;paysans.&lt;/p&gt;&#xA;&lt;p&gt;Le marxisme enseigné passait pourtant par un filtre : au moins pendant les&#xA;premières années de la révolution, les cadres et enseignants du Front&#xA;n&amp;rsquo;évoquaient pas la critique marxiste de la religion, sans doute pour éviter des&#xA;conflits avec une population composée de musulmans très pieux. Au contraire,&#xA;sans proposer d&amp;rsquo;enseignement religieux, ils affirmaient qu&amp;rsquo;il n&amp;rsquo;y avait pas de&#xA;contradiction entre le socialisme et l&amp;rsquo;islam. Sur ce point, l&amp;rsquo;autrice est&#xA;d&amp;rsquo;accord. Pour elle, avant la révolution, la société dhofarie était déjà basée&#xA;sur une sorte de communisme tribal dans lequel l&amp;rsquo;État était presque absent. Elle&#xA;affirme que la population de la péninsule arabique était déjà à l&amp;rsquo;aise avec&#xA;l&amp;rsquo;idée de la domination du prolétariat, car cette idée se trouve dans le Coran,&#xA;et elle cite le verset : « Or, Nous voulions apporter Notre aide à ces opprimés&#xA;sur Terre, pour faire d&amp;rsquo;eux des dirigeants et des héritiers » (28:5)&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.&#xA;Il s&amp;rsquo;agit d&amp;rsquo;un des versets préférés de la gauche islamique depuis les années&#xA;1970.&lt;/p&gt;&#xA;&lt;p&gt;En 1970, la Grande-Bretagne a remplacé le sultan d&amp;rsquo;Oman par son fils Qaboos.&#xA;Sans se démarquer de l&amp;rsquo;autoritarisme de son père, Qaboos a cherché non seulement&#xA;à vaincre la révolution sur le plan militaire, mais aussi à gagner le soutien de&#xA;la population, en favorisant le développement économique, en construisant des&#xA;écoles publiques, en restaurant certains des privilèges des tribus, en&#xA;proclamant sans cesse que l&amp;rsquo;islam était le fondement de son règne et en&#xA;affirmant que le Front populaire s&amp;rsquo;opposait à l&amp;rsquo;islam. Selon Ja‘bub, bien que&#xA;cette accusation ait longtemps été fausse, les dirigeants du Front, ayant&#xA;l&amp;rsquo;impression d&amp;rsquo;avoir acquis la confiance totale de la population, ont fini par&#xA;dire ouvertement que la religion est l&amp;rsquo;opium du peuple. Leurs soldats se sont&#xA;donc rebellés contre eux et cela a entraîné une scission au sein du Front. Pour&#xA;Ja‘bub, si les révolutionnaires avaient poursuivi leur utilisation sélective de&#xA;la pensée marxiste, en l&amp;rsquo;adaptant à la société locale et à ses croyances&#xA;islamiques, ils auraient pu avoir plus de succès que tous les autres mouvements&#xA;de gauche dans le monde arabe.&lt;/p&gt;&#xA;&lt;p&gt;Après la défaite militaire de la révolution en 1975, qu&amp;rsquo;est-ce qu&amp;rsquo;il est advenu&#xA;du changement social qu&amp;rsquo;elle avait amené ? Les réponses que Ja‘bub apportent à&#xA;cette question sont parmi les parties les plus intéressantes du livre. Les&#xA;révolutionnaires ont encouragé et fêté des mariages entre personnes issues des&#xA;tribus et anciens esclaves. Les anciens élèves se souviennent de s&amp;rsquo;être réjouis&#xA;de ces mariages. Pendant la révolution, les mots associés au racisme sont&#xA;devenus répugnants pour eux et ils se sont même interdit d&amp;rsquo;utiliser le mot «&#xA;noir » pour désigner la couleur de la peau de quelqu&amp;rsquo;un. C&amp;rsquo;est avec fierté&#xA;qu&amp;rsquo;ils disent à l&amp;rsquo;autrice que, à l&amp;rsquo;époque, comme ils étaient convaincus que le&#xA;tribalisme était injuste et réactionnaire, ils ont spontanément cessé d&amp;rsquo;écrire&#xA;le nom de leur tribu quand ils écrivaient leur nom. Mais Ja‘bub observe que,&#xA;quand elle les a rencontrés pour la première fois, la première question qu&amp;rsquo;ils&#xA;lui ont posée était « De quelle tribu êtes-vous ? » et que leur conversation&#xA;était parsemée de remarques sur la qualité de la tribu de telle ou telle&#xA;personne. L&amp;rsquo;esclavage est toujours interdit, mais le mépris des tribus envers&#xA;les anciens esclaves est revenu. De même, les femmes qui ont été scolarisées par&#xA;le Front populaire sont aujourd&amp;rsquo;hui parmi les Omanaises plus conservatrices et&#xA;les plus attachées aux signes extérieurs de la tradition patriarcale. Certes,&#xA;elles sont devenus médecins, enseignantes ou managers. Mais elles ont répudié le&#xA;féminisme que le Front populaire avait prôné et pratiqué.&lt;/p&gt;&#xA;&lt;p&gt;Selon Ja‘bub, la théorie marxiste ne peut pas être appliquée telle quelle à&#xA;l&amp;rsquo;ordre social tribal qui existait à Dhofar avant la révolution. Cependant, il y&#xA;avait de l&amp;rsquo;injustice sociale, et une grande partie des fondateurs et dirigeants&#xA;de la révolution appartenaient aux catégories sociales non tribales qui&#xA;souffraient de cette injustice. Ce livre, qui est devenu une référence&#xA;importante pour les recherches historiques sur la péninsule arabique, constitue&#xA;donc une contribution utile aux débats sur la pertinence des concepts marxistes&#xA;dans différents contextes sociaux. Il donne aussi un aperçu fascinant de la&#xA;capacité d&amp;rsquo;une population à adhérer sincèrement à des valeurs révolutionnaires&#xA;dans un quasi-État construit par des militants, puis à les abandonner avec&#xA;l&amp;rsquo;arrivée de l&amp;rsquo;État suivant.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;bibliographie&#34;&gt;&#xA;  Bibliographie&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#bibliographie&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Geer, Benjamin. 2025. “Mona Salem Said Ja‘bub, Qiyadat al-mujtama‘ nahw al-taghyir: al-tajriba al-tarbawiyya li-thawrat Dhufar (1969-1992) [Conducir la sociedad hacia el cambio: la experiencia educativa de la revolución de Dhofar].” &lt;em&gt;Prismas. Revista de historia intelectual&lt;/em&gt; 29 (1): 412–14. &lt;a href=&#34;https://doi.org/10.48160/18520499prismas29.1626&#34; target=&#34;_blank&#34;&gt;https://doi.org/10.48160/18520499prismas29.1626&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;Geer, « Mona Ja‘bub, Qiyadat al-mujtama‘ nahw al-taghyir ».&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;Traduction de Mohammed Chiadmi.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</description>
    </item>
    <item>
      <title>Créer une machine virtuelle en Rust</title>
      <link>https://benjamingeer.name/fr/post/organiclox/</link>
      <pubDate>Sun, 12 Oct 2025 00:00:00 +0000</pubDate>
      <guid>https://benjamingeer.name/fr/post/organiclox/</guid>
      <description>&lt;h2 class=&#34;heading&#34; id=&#34;aperçu&#34;&gt;&#xA;  Aperçu&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#aper%c3%a7u&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Pour m&amp;rsquo;aider à apprendre le langage Rust, j&amp;rsquo;ai décidé de réaliser un&#xA;interpréteur pour Lox, le langage de script que Robert Nystrom a créé pour son&#xA;livre &lt;a href=&#34;https://craftinginterpreters.com/&#34; target=&#34;_blank&#34;&gt;&lt;em&gt;Crafting Interpreters&lt;/em&gt;&lt;/a&gt;. Je&#xA;m&amp;rsquo;intéresse aux langages de script qui sont destinés à être embarqués dans des&#xA;applications, et cet exercice m&amp;rsquo;a semblé un bon moyen d&amp;rsquo;en savoir plus sur la&#xA;construction de ce type de langage.&lt;/p&gt;&#xA;&lt;p&gt;Le livre de Nystrom présente, étape par étape, le développement de deux versions&#xA;de l&amp;rsquo;interpréteur. Alors que la première, en Java, parcourt un arbre de syntaxe&#xA;abstraite (AST) pour exécuter un script, la deuxième, en C, comporte une machine&#xA;virtuelle qui exécute du bytecode. Cette deuxième version m&amp;rsquo;intéressait&#xA;davantage. Au fil des ans, j&amp;rsquo;avais réalisé deux interpréteurs qui parcourent des&#xA;arbres de syntaxe abstraite, en commençant par &lt;a href=&#34;https://freemarker.apache.org/&#34; target=&#34;_blank&#34;&gt;Apache&#xA;FreeMarker&lt;/a&gt;, ainsi qu&amp;rsquo;&lt;a href=&#34;https://doi.org/10.3233/sw-200386&#34; target=&#34;_blank&#34;&gt;un compilateur source à&#xA;source optimisant&lt;/a&gt; utilisant l&amp;rsquo;inférence de&#xA;types. Mais je n&amp;rsquo;avais pas encore fait de machine virtuelle. L&amp;rsquo;idée me rappelait&#xA;de bons souvenirs de programmation en assembleur sur l&amp;rsquo;&lt;a href=&#34;https://en.wikipedia.org/wiki/Apple_II&#34; target=&#34;_blank&#34;&gt;Apple&#xA;II&lt;/a&gt; quand j&amp;rsquo;avais quinze ans. Le jeu&#xA;d&amp;rsquo;instructions de la machine virtuelle de Nystrom est plus simple que celle du&#xA;processeur &lt;a href=&#34;https://fr.wikipedia.org/wiki/MOS_Technology_6502&#34; target=&#34;_blank&#34;&gt;Motorola 6502&lt;/a&gt; de&#xA;l&amp;rsquo;Apple II, mais le principe est le même. J&amp;rsquo;ai donc sauté la première partie du&#xA;livre pour aller directement à celle où il s&amp;rsquo;agit de la machine virtuelle.&lt;/p&gt;&#xA;&lt;p&gt;Le résultat est &lt;a href=&#34;https://codeberg.org/benjamingeer/organiclox&#34; target=&#34;_blank&#34;&gt;OrganicLox&lt;/a&gt;. La&#xA;conception est globalement celle présentée dans le livre, mais j&amp;rsquo;ai essayé de&#xA;coder dans un Rust courant, en visant des performances raisonnables, sans écrire&#xA;de code non sécurisé. Les fonctionnalités d&amp;rsquo;OrganicLox devraient être identiques&#xA;à celles du programme &lt;code&gt;clox&lt;/code&gt; de Nystrom : au moins, ses &lt;a href=&#34;https://github.com/munificent/craftinginterpreters/?tab=readme-ov-file#testing-your-implementation&#34; target=&#34;_blank&#34;&gt;246 tests&#xA;automatisés&lt;/a&gt;&#xA;passent.&lt;/p&gt;&#xA;&lt;p&gt;J&amp;rsquo;ai décidé de ne pas créer mon propre ramasse-miettes, car tout le monde semble&#xA;s&amp;rsquo;accorder à dire que les ramasse-miettes sont &lt;a href=&#34;https://manishearth.github.io/blog/2021/04/05/a-tour-of-safe-tracing-gc-designs-in-rust/&#34; target=&#34;_blank&#34;&gt;particulièrement difficiles à&#xA;réaliser en&#xA;Rust&lt;/a&gt;.&#xA;Par souci de simplicité, j&amp;rsquo;ai opté plutôt pour le comptage des références (au&#xA;moyen de &lt;a href=&#34;https://doc.rust-lang.org/std/rc/struct.Rc.html&#34; target=&#34;_blank&#34;&gt;Rc&lt;/a&gt;). Sur la branche&#xA;&lt;a href=&#34;https://codeberg.org/benjamingeer/organiclox/src/branch/main&#34; target=&#34;_blank&#34;&gt;&lt;code&gt;main&lt;/code&gt;&lt;/a&gt;, cela&#xA;veut dire que les cycles de propriétés d&amp;rsquo;objets ne seront pas nettoyés. Sur la&#xA;branche&#xA;&lt;a href=&#34;https://codeberg.org/benjamingeer/organiclox/src/branch/with_dumpster_gc&#34; target=&#34;_blank&#34;&gt;&lt;code&gt;with_dumpster_gc&lt;/code&gt;&lt;/a&gt;,&#xA;j&amp;rsquo;ai remplacé &lt;code&gt;Rc&lt;/code&gt; par la crate&#xA;&lt;a href=&#34;https://codeberg.org/benjamingeer/organiclox/src/branch/main&#34; target=&#34;_blank&#34;&gt;dumpster&lt;/a&gt;, qui&#xA;assure le comptage des références et nettoie aussi les cycles.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;ce-que-jai-préféré&#34;&gt;&#xA;  Ce que j&amp;rsquo;ai préféré&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#ce-que-jai-pr%c3%a9f%c3%a9r%c3%a9&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;J&amp;rsquo;ai beaucoup aimé ce livre : les explications claires de Nystrom, ses&#xA;illustrations utiles, son style léger et son humour ont rendu le livre&#xA;agréable à lire.&lt;/p&gt;&#xA;&lt;p&gt;Pour moi, la mise en œuvre des variables locales et des fermetures dans une&#xA;machine virtuelle à pile ont été parmi les aspects les plus intéressants de la&#xA;conception que présente Nystrom, conception qui s&amp;rsquo;inspire largement de &lt;a href=&#34;https://www.lua.org/doc/jucs05.pdf&#34; target=&#34;_blank&#34;&gt;celle de&#xA;l&amp;rsquo;interpréteur Lua&lt;/a&gt;. J&amp;rsquo;ai aimé apprendre que&#xA;le compilateur &lt;a href=&#34;https://craftinginterpreters.com/local-variables.html&#34; target=&#34;_blank&#34;&gt;associe les variables locales à des positions spécifiques sur la&#xA;pile&lt;/a&gt;, de sorte que la&#xA;machine virtuelle n&amp;rsquo;a besoin de connaître que ces positions et non pas les noms&#xA;des variables concernés.&lt;/p&gt;&#xA;&lt;p&gt;La mise en œuvre des &lt;em&gt;upvalues&lt;/em&gt;, à savoir les variables qui sont capturées par&#xA;les fermetures et qui doivent donc éventuellement être allouées sur le tas, n&amp;rsquo;a&#xA;pas été simple à faire correctement. En corrigeant un bogue, j&amp;rsquo;ai été heureux de&#xA;me rendre compte que &lt;a href=&#34;https://github.com/munificent/craftinginterpreters/blob/master/test/function/local_recursion.lox&#34; target=&#34;_blank&#34;&gt;l&amp;rsquo;appel récursif d&amp;rsquo;une function définie dans une portée&#xA;locale&lt;/a&gt;&#xA;nécessite que la fermeture de la fonction soit une des ses propres &lt;em&gt;upvalues&lt;/em&gt;.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;ce-que-jaurais-souhaité&#34;&gt;&#xA;  Ce que j&amp;rsquo;aurais souhaité&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#ce-que-jaurais-souhait%c3%a9&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Les explications de Nystrom sont tantôt ascendantes, tantôt descendantes.&#xA;L&amp;rsquo;approche ascendante a présenté plus de difficultés quant à la traduction de&#xA;sa conception en Rust, car je devais deviner où il voulait en venir. Plusieurs&#xA;fois j&amp;rsquo;ai dû remanier beaucoup de code parce que je n&amp;rsquo;avais pas deviné juste.&#xA;Comme l&amp;rsquo;implémentation de Lox dans toutes sortes de langages de programmation&#xA;semble être &lt;a href=&#34;https://github.com/munificent/craftinginterpreters/wiki/Lox-implementations&#34; target=&#34;_blank&#34;&gt;un exercice courant&lt;/a&gt;,&#xA;il aurait été utile d&amp;rsquo;avoir plus souvent une vue d&amp;rsquo;ensemble de la conception.&lt;/p&gt;&#xA;&lt;p&gt;Cela m&amp;rsquo;a fait plaisir de découvrir &lt;a href=&#34;https://craftinginterpreters.com/compiling-expressions.html&#34; target=&#34;_blank&#34;&gt;la technique de Pratt pour construire un analyseur&#xA;syntaxique descendant reposant sur la précédence des&#xA;opérateurs&lt;/a&gt;&#xA;et de constater qu&amp;rsquo;il est vraiment possible de générer du bytecode sans d&amp;rsquo;abord&#xA;construire un AST. Mais il aurait peut-être été plus&#xA;utile de construire un AST et d&amp;rsquo;apprendre quelque chose sur la conception d&amp;rsquo;une&#xA;deuxième phase pour optimiser le bytecode.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;la-performance&#34;&gt;&#xA;  La performance&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#la-performance&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;L&amp;rsquo;optimisation principale que j&amp;rsquo;ai faite au départ a été de faire en sorte que&#xA;l&amp;rsquo;analyseur lexical mette tous les identificateurs dans un pool de chaînes de&#xA;caractères (en utilisant&#xA;&lt;a href=&#34;https://docs.rs/string-interner/latest/string_interner/&#34; target=&#34;_blank&#34;&gt;string_interner&lt;/a&gt;),&#xA;pour que ni le compilateur ni la machine virtuelle aient à comparer des chaînes&#xA;représentant des identificateurs.&lt;/p&gt;&#xA;&lt;p&gt;Après avoir fini &lt;a href=&#34;https://craftinginterpreters.com/calls-and-functions.html&#34; target=&#34;_blank&#34;&gt;le chapitre&#xA;24&lt;/a&gt;, j&amp;rsquo;ai passé un&#xA;peu de temps à me pencher sur la performance, en suivant les conseils du &lt;a href=&#34;https://nnethercote.github.io/perf-book&#34; target=&#34;_blank&#34;&gt;Rust&#xA;Performance Book&lt;/a&gt;. J&amp;rsquo;ai fait des tests&#xA;de performance avec &lt;a href=&#34;https://docs.rs/criterion/latest/criterion/&#34; target=&#34;_blank&#34;&gt;criterion&lt;/a&gt; et&#xA;du profilage avec &lt;a href=&#34;https://perfwiki.github.io/main/&#34; target=&#34;_blank&#34;&gt;perf&lt;/a&gt; et&#xA;&lt;a href=&#34;https://github.com/KDAB/hotspot&#34; target=&#34;_blank&#34;&gt;hotspot&lt;/a&gt;, j&amp;rsquo;ai ajusté &lt;a href=&#34;https://nnethercote.github.io/perf-book/build-configuration.html#maximizing-runtime-speed&#34; target=&#34;_blank&#34;&gt;la configuration du&#xA;compilateur&#xA;Rust&lt;/a&gt;&#xA;and j&amp;rsquo;ai marqué quelques fonctions&#xA;&lt;a href=&#34;https://nnethercote.github.io/perf-book/inlining.html&#34; target=&#34;_blank&#34;&gt;&lt;code&gt;inline&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Ensuite j&amp;rsquo;ai regardé &lt;a href=&#34;https://github.com/munificent/craftinginterpreters/wiki/Lox-implementations#rust&#34; target=&#34;_blank&#34;&gt;quelques autres versions de Lox en&#xA;Rust&lt;/a&gt;&#xA;et j&amp;rsquo;ai remarqué que tout le monde semble avoir eu du mal à obtenir des&#xA;performances proches de celles du &lt;code&gt;clox&lt;/code&gt; de&#xA;Nystrom et que les versions qui y arrivent comportent beaucoup de code&#xA;non sécurisé, ce que je voulais éviter.&lt;/p&gt;&#xA;&lt;p&gt;Je recommande vivement &lt;a href=&#34;https://ceronman.com/blog/my-experience-crafting-an-interpreter-with-rust/&#34; target=&#34;_blank&#34;&gt;billet de&#xA;blog&lt;/a&gt;&#xA;de Manuel Cerón sur sa tentative impressionnante, déterminée et partiellement&#xA;réussie d&amp;rsquo;égaler la vitesse de &lt;code&gt;clox&lt;/code&gt; en Rust en écrivant de plus en plus de&#xA;code non sécurisé.&lt;/p&gt;&#xA;&lt;p&gt;À titre de comparaison, voici les résultats de l&amp;rsquo;exécution de quelques-uns des&#xA;&lt;a href=&#34;https://github.com/munificent/craftinginterpreters/tree/master/test/benchmark&#34; target=&#34;_blank&#34;&gt;tests de performance de Nystrom&lt;/a&gt;&#xA;sur les versions suivantes :&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Le &lt;code&gt;clox&lt;/code&gt; de Nystrom&lt;/li&gt;&#xA;&lt;li&gt;La version sécurisée du &lt;code&gt;loxido&lt;/code&gt; de Cerón&lt;/li&gt;&#xA;&lt;li&gt;La version non sécurisée de &lt;code&gt;loxido&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;OrganicLox avec &lt;code&gt;Rc&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;OrganicLox avec le ramasse-miettes &lt;code&gt;dumpster&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;figure&gt;&lt;img src=&#34;https://benjamingeer.name/fr/post/organiclox/lox-benchmarks-fr.svg&#34;&#xA;    alt=&#34;un diagramme à barres de résultats de tests de performance&#34; width=&#34;100%&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;OrganicLox avec &lt;code&gt;Rc&lt;/code&gt; est donc deux à quatre fois plus lent que &lt;code&gt;clox&lt;/code&gt;, ce qui&#xA;est peut-être typique des interpréteurs réalisés en Rust &lt;a href=&#34;https://github.com/raviqqe/stak/blob/939f7bae9f188027d2f9e2cdc62c3baa76be36ed/README.md?plain=1#L174&#34; target=&#34;_blank&#34;&gt;par rapport à ceux&#xA;réalisés en&#xA;C&lt;/a&gt;.&#xA;La version avec &lt;code&gt;dumpster&lt;/code&gt; est beaucoup plus lente. Il semble clair qu&amp;rsquo;un&#xA;ramasse-miettes rapide est essentiel pour une machine virtuelle très&#xA;performante.&lt;/p&gt;&#xA;&lt;p&gt;Quelle est l&amp;rsquo;importance de ces différences ? Les tests de performance sont&#xA;conçus pour simuler des scénarios extrêmes, par exemple en utilisant de longues&#xA;boucles ou la récursivité profonde, ou en créant une charge de travail&#xA;importante pour le ramasse-miettes. Ils ne sont donc pas forcément&#xA;représentatifs des cas d&amp;rsquo;utilisation réels. Il arrive souvent que les scripts&#xA;exécutés par une application dans un interpréteur embarqué sont courts et font&#xA;très peu de travail. On pourrait se faire une idée plus réaliste de la&#xA;performance d&amp;rsquo;une machine virtuelle dans un tel scénario en exécutant la suite&#xA;de tests d&amp;rsquo;intégration de Nystrom, qui exécute 246 scripts courts en Lox et&#xA;vérifie leurs sorties. Voici une comparaison :&lt;/p&gt;&#xA;&lt;figure&gt;&lt;img src=&#34;https://benjamingeer.name/fr/post/organiclox/lox-tests-fr.svg&#34;&#xA;    alt=&#34;a bar chart of test suite running times&#34; width=&#34;100%&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;Dans une application où chaque cycle CPU compte, les écarts entre les&#xA;performances de ces différentes implémentations pourraient avoir beaucoup&#xA;d&amp;rsquo;importance. Mais dans d&amp;rsquo;autres cas d&amp;rsquo;utilisation, ils pourraient être&#xA;insignifiants.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;dautres-approches-possibles&#34;&gt;&#xA;  D&amp;rsquo;autres approches possibles&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#dautres-approches-possibles&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Il est tentant d&amp;rsquo;essayer d&amp;rsquo;ajouter un compilateur à la volée (JIT) pour&#xA;améliorer la performance de l&amp;rsquo;interpréteur, soit en en écrivant un à partir de&#xA;zéro, soit en en utilisant un &lt;em&gt;backend&lt;/em&gt; existant comme &lt;a href=&#34;https://llvm.org/&#34; target=&#34;_blank&#34;&gt;LLVM&lt;/a&gt;&#xA;ou &lt;a href=&#34;https://cranelift.dev/&#34; target=&#34;_blank&#34;&gt;Cranelift&lt;/a&gt;.&#xA;&lt;a href=&#34;https://blog.nlnetlabs.nl/introducing-roto-a-compiled-scripting-language-for-rust&#34; target=&#34;_blank&#34;&gt;Roto&lt;/a&gt;&#xA;et&#xA;&lt;a href=&#34;https://blog.nlnetlabs.nl/introducing-roto-a-compiled-scripting-language-for-rust/&#34; target=&#34;_blank&#34;&gt;Dora&lt;/a&gt;&#xA;sont des exemples en Rust de cette approche. Mais même si on adopte cette&#xA;démarche, il n&amp;rsquo;est pas facile d&amp;rsquo;atteindre un haut niveau de performance. Dans&#xA;&lt;a href=&#34;https://blog.miguelgrinberg.com/post/python-3-14-is-here-how-fast-is-it&#34; target=&#34;_blank&#34;&gt;ces tests de&#xA;performance&lt;/a&gt;,&#xA;le nouveau JIT de Python n&amp;rsquo;a aucun effet mesurable sur les performances (voir&#xA;aussi &lt;a href=&#34;https://dinfuehr.com/blog/dora-implementing-a-jit-compiler-with-rust/#benchmarks&#34; target=&#34;_blank&#34;&gt;ces résultats de tests de la performance de&#xA;Dora&lt;/a&gt;).&lt;/p&gt;&#xA;&lt;p&gt;Voilà une raison d&amp;rsquo;envisager d&amp;rsquo;utiliser un interpréteur existant qui a déjà&#xA;bénéficié d&amp;rsquo;années de développement, plutôt que d&amp;rsquo;en créer un nouveau. Le&#xA;langage &lt;a href=&#34;https://www.lua.org/&#34; target=&#34;_blank&#34;&gt;Lua&lt;/a&gt; est une option largement utilisée, mais il&#xA;n&amp;rsquo;est pas assez rapide pour certaines applications. La machine virtuelle&#xA;&lt;a href=&#34;https://luajit.org/&#34; target=&#34;_blank&#34;&gt;LuaJIT&lt;/a&gt; est un ordre de grandeur plus rapide que la&#xA;machine virtuelle Lua standard pour certains cas d&amp;rsquo;utilisation, mais c&amp;rsquo;est un&#xA;&lt;a href=&#34;https://www.polarsignals.com/blog/posts/2024/11/13/lua-unwinding&#34; target=&#34;_blank&#34;&gt;compilateur à la volée basé sur les arbres de&#xA;traces&lt;/a&gt;, ce&#xA;qui a des avantages et des inconvénients. Les développeurs de Lua ont publié un&#xA;&lt;a href=&#34;https://www.inf.puc-rio.br/~roberto/docs/pallene-sblp.pdf&#34; target=&#34;_blank&#34;&gt;article intéressant&lt;/a&gt;&#xA;qui traite des limites de cette approche et propose une autre solution (un&#xA;langage supplémentaire à typage statique, un peu comme&#xA;&lt;a href=&#34;https://cython.org/&#34; target=&#34;_blank&#34;&gt;Cython&lt;/a&gt;).&lt;/p&gt;&#xA;&lt;p&gt;Pour certains cas d&amp;rsquo;utilisation, si des scripts embarqués ne font pas beaucoup&#xA;de travail, leurs performances pourraient ne pas être critiques. S&amp;rsquo;ils font&#xA;tellement de travail que leurs performances sont insuffisantes, une autre option&#xA;consiste à ne pas intégrer d&amp;rsquo;interpréteur du tout. Cloudflare, qui avait investi&#xA;massivement pendant plus de 20 ans dans des scripts en utilisant LuaJIT embarqué&#xA;dans &lt;a href=&#34;https://openresty.org/en/&#34; target=&#34;_blank&#34;&gt;OpenResty&lt;/a&gt;, &lt;a href=&#34;https://blog.cloudflare.com/20-percent-internet-upgrade/&#34; target=&#34;_blank&#34;&gt;les a récemment remplacés par du&#xA;code Rust&lt;/a&gt;.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Calculer des mesures de centralité avec le réseau de transport en commun parisien</title>
      <link>https://benjamingeer.name/fr/post/paris-rail-centrality/</link>
      <pubDate>Fri, 29 Aug 2025 00:00:00 +0000</pubDate>
      <guid>https://benjamingeer.name/fr/post/paris-rail-centrality/</guid>
      <description>&lt;p&gt;J&amp;rsquo;ai pensé qu&amp;rsquo;il serait intéressant d&amp;rsquo;essayer un peu d&amp;rsquo;&lt;a href=&#34;https://fr.wikipedia.org/wiki/Th%C3%A9orie_des_r%C3%A9seaux&#34; target=&#34;_blank&#34;&gt;analyse de réseau &lt;/a&gt; élémentaire en utilisant &lt;a href=&#34;https://www.ratp.fr/plans&#34; target=&#34;_blank&#34;&gt;le réseau du métro et du RER parisiens&lt;/a&gt;, en commençant par des indices de &lt;a href=&#34;https://fr.wikipedia.org/wiki/Centralit%C3%A9&#34; target=&#34;_blank&#34;&gt;centralité&lt;/a&gt;. Il s&amp;rsquo;agit de mesures qui classent les sommets d&amp;rsquo;un graphe en fonction de leur importance, selon une définition quelconque de l&amp;rsquo;importance. Par exemple, dans un réseau de transport, la centralité d&amp;rsquo;une station pourrait donner une indication de la probabilité que les passagers passent par cette station au cours de leur itinéraire. Un opérateur de transports en commun pourrait utiliser ces informations pour évaluer les inconvénients que causerait la fermeture de certaines stations, par exemple en raison d&amp;rsquo;inondations ou de travaux, et pour l&amp;rsquo;aider à identifier les moyens les plus efficaces d&amp;rsquo;améliorer la résilience du réseau. J&amp;rsquo;utiliserai ici &lt;a href=&#34;https://www.python.org&#34; target=&#34;_blank&#34;&gt;Python&lt;/a&gt;, &lt;a href=&#34;https://networkx.org&#34; target=&#34;_blank&#34;&gt;networkx&lt;/a&gt; et &lt;a href=&#34;https://sqlite.org&#34; target=&#34;_blank&#34;&gt;SQLite&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;construire-le-graphe&#34;&gt;&#xA;  Construire le graphe&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#construire-le-graphe&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;J&amp;rsquo;ai choisi ici de faire un seul graphe qui comprend le métro et le RER. Le premier problème est de construire ce graphe en établissant la liste de liens et la liste de sommets. Les établissements qui régissent les transports en commun parisiens ne fournissent pas de tel jeu de données, mais ils fournissent un &lt;a href=&#34;https://www.data.gouv.fr/datasets/horaires-prevus-sur-les-lignes-de-transport-en-commun-dile-de-france-gtfs-datahub/&#34; target=&#34;_blank&#34;&gt;jeu de données GTFS&lt;/a&gt; qui représente les horaires prévus sur toutes les lignes de transport pendant les 30 prochains jours. (Je tiens à remercier &lt;a href=&#34;https://masto.ai/@bovine3dom&#34; target=&#34;_blank&#34;&gt;Oliver Blanthorn&lt;/a&gt; de me l&amp;rsquo;avoir signalé.) Les données GTFS représentent les courses (les séquences d&amp;rsquo;arrêts) que les trains devraient parcourir sur les lignes de métro ou de RER. Pour construire la liste de liens du réseau, nous pouvons parcourir chaque course, en enregistrant un lien entre chaque arrêt et l&amp;rsquo;arrêt suivant. Certaines courses vont dans une direction, d&amp;rsquo;autres dans la direction inverse, et beaucoup ne comprennent pas tous les arrêts de la ligne, mais en les parcourant toutes, nous devrions accumuler un graphe orienté complet du réseau. Il faudra parcourir environ 64 000 courses, qui comprennent au total presque 1,5 million d&amp;rsquo;arrêts, et une grande partie des données sera redonante pour nous, mais cela n&amp;rsquo;a pas d&amp;rsquo;importance tant que le traitement des données ne prend pas trop de temps.&lt;/p&gt;&#xA;&lt;p&gt;Il s&amp;rsquo;agit donc de réaliser un procédé &lt;a href=&#34;https://fr.wikipedia.org/wiki/Extract-transform-load&#34; target=&#34;_blank&#34;&gt;ETL (Extract, transform, load)&lt;/a&gt;. D&amp;rsquo;abord j&amp;rsquo;ai créé &lt;a href=&#34;https://framagit.org/benjamingeer/benjamingeer/-/tree/main/notebook-data/paris-rail-data/download-data.sh&#34; target=&#34;_blank&#34;&gt;un script shell&lt;/a&gt; qui télécharge les données GTFS, ainsi que plusieurs fichiers d&amp;rsquo;un jeu de données qui s&amp;rsquo;appelle &lt;a href=&#34;https://data.iledefrance-mobilites.fr/explore/dataset/referentiel-des-lignes/information/?disjunctive.transportsubmode&amp;amp;disjunctive.operatorname&amp;amp;disjunctive.networkname&amp;amp;disjunctive.transportmode&#34; target=&#34;_blank&#34;&gt;Référentiel des lignes de transport en commun d’île-de-France&lt;/a&gt;, dont nous aurons également besoin. Comme tous ces fichiers sont au format CSV et utilisent des identifiants uniques pour relier les données des différents fichiers, notre tâche sera plus facile si nous utilisons une base de données relationnelle. Dans un &lt;a href=&#34;https://framagit.org/benjamingeer/benjamingeer/-/tree/main/notebook-data/paris-rail-data/import-data.sh&#34; target=&#34;_blank&#34;&gt;deuxième script shell&lt;/a&gt;, j&amp;rsquo;importe les fichiers pertinents dans une base de données intermédiaire gérée par SQLite et je crée quelques index pour accélérer les requêtes de l&amp;rsquo;étape de transformation. Ce script s&amp;rsquo;exécute en 21 secondes environ sur mon ordinateur portable et la taille de la base de données obtenue est de 2,1 Go.&lt;/p&gt;&#xA;&lt;p&gt;Enfin, j&amp;rsquo;ai créé &lt;a href=&#34;https://framagit.org/benjamingeer/benjamingeer/-/tree/main/notebook-data/paris-rail-data/build-graph.py&#34; target=&#34;_blank&#34;&gt;un script Python&lt;/a&gt; pour les étapes de transformation et de chargement. Il lit la base de données intermédiaire et construit la base de données de sortie, qui ne contient que la table de liens et la table de sommets. Comme la base de données de sortie est petite (132 Ko), le script la crée en mémore pour améliorer la performance de cette étape, puis la sauvegarde quand elle est complète. L&amp;rsquo;exécution de ce script prend environ 8 secondes.&lt;/p&gt;&#xA;&lt;p&gt;Dans le Référentiel, les liens entre le métro et le RER sont représentés par des zones de correspondance et des pôles d&amp;rsquo;échange, qui peuvent comprendre plusieurs stations reliées par des couloirs. Pour inclure ces relations dans le graphe, j&amp;rsquo;ai choisi d&amp;rsquo;ajouter des liens entre toutes les stations faisant partie du même groupe.&lt;/p&gt;&#xA;&lt;p&gt;La base de données de sortie représente un multigraphe orienté, puisque deux stations peuvent être reliées par plusieurs lignes. Dans un tel cas, nous pouvons considérer que les deux stations en question ont un lien plus fort que deux stations qui ne sont reliées que par une seule ligne. Toutes choses étant égales par ailleurs, plus il y a de lignes entre deux stations, plus il y aura de passagers qui voyagent entre les deux. Nous conserverons ces informations sur les liens multiples en faisant nos calculs.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;visualiser-des-parties-du-graphe&#34;&gt;&#xA;  Visualiser des parties du graphe&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#visualiser-des-parties-du-graphe&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Visualisons d&amp;rsquo;abord une partie des données pour vérifier qu&amp;rsquo;elles sont correctes. Nous pouvons créer une fonction qui affiche le graphe d&amp;rsquo;un réseau de transport. Ici, nous nous intéressons uniquement aux sommets et aux liens, et non pas à leur position géographique. Pour repérer facilement les lignes, nous pouvons utiliser les couleurs précisées pour le &lt;a href=&#34;https://www.ratp.fr/plans&#34; target=&#34;_blank&#34;&gt;plan du réseau&lt;/a&gt;, qui se trouvent dans le jeu de données GTFS, ainsi que le noir pour les liens que j&amp;rsquo;ai ajoutés pour les zones de correspondance et les pôles d&amp;rsquo;échange.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;42&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;43&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;44&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;45&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;46&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;config&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;InlineBackend&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;figure_formats&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;svg&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;sqlite3&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pandas&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pd&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;networkx&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;nx&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;numpy&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;np&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;matplotlib.pyplot&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;plt&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;itertools&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;it&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;draw_graph&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;height&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;label_x_offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;plt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;figure&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;figsize&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;height&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;plt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;margins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.18&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;plt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;pos&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nx_agraph&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;graphviz_layout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;prog&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;dot&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# See https://networkx.org/documentation/stable/auto_examples/drawing/plot_multigraphs.html&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;connectionstyle&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;arc3,rad=&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;r&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;it&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;accumulate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.15&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;draw_networkx_nodes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;node_size&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;30&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;node_color&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;#000000&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;edge_colors&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;#&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;source_node_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;][&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target_node_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;][&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;edge_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;][&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;route_color&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;source_node_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;target_node_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;edge_key&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;edges&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;draw_networkx_edges&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;edge_color&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;edge_colors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;connectionstyle&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;connectionstyle&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;label_pos&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;node_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node_pos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;label_x_offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;node_pos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;node_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;node_pos&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pos&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;items&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;text&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;draw_networkx_labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;label_pos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get_node_attributes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;node_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;horizontalalignment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;left&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;verticalalignment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;bottom&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;font_size&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;t&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;items&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set_rotation&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Essayons avec les lignes de métro 1 et 4 et le RER A:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;42&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;43&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;44&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;45&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;46&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;47&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;48&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;49&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;50&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;DATABASE&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;../../../notebook-data/paris-rail-data/paris-graph.db&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;conn&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sqlite3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;connect&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;file:&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DATABASE&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;?mode=ro&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;nodes&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pd&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read_sql_query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;select distinct&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        nodes.node_id, nodes.node_name&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    from nodes&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    inner join edges on&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        nodes.node_id = edges.source_node_id or&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        nodes.node_id = edges.target_node_id&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    where&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        (edges.route_type = 1 and edges.route_name = &amp;#39;1&amp;#39;) or&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        (edges.route_type = 1 and edges.route_name = &amp;#39;4&amp;#39;) or&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        (edges.route_type = 2 and edges.route_name = &amp;#39;A&amp;#39;) or&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        (edges.route_type is null and&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;            (edges.route_name = &amp;#39;PdE Châtelet - Les Halles&amp;#39; or&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;            edges.route_name = &amp;#39;ZdC Gare de Lyon&amp;#39;))&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;conn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;index_col&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;node_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;edges&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pd&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read_sql_query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;select * from edges where&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        (edges.route_type = 1 and edges.route_name = &amp;#39;1&amp;#39;) or&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        (edges.route_type = 1 and edges.route_name = &amp;#39;4&amp;#39;) or&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        (edges.route_type = 2 and edges.route_name = &amp;#39;A&amp;#39;) or&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        (edges.route_type is null and&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;            (edges.route_name = &amp;#39;PdE Châtelet - Les Halles&amp;#39; or&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;            edges.route_name = &amp;#39;ZdC Gare de Lyon&amp;#39;))&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;conn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;replace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;from_pandas_edgelist&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;edges&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;source_node_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;target&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;target_node_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;edge_attr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;create_using&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MultiDiGraph&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;node_attributes&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nodes&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;to_dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;orient&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;index&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set_node_attributes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;node_attributes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;draw_graph&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Les lignes de métro 1 et 4 et le RER A&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;height&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;label_x_offset&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;&lt;img src=&#34;https://benjamingeer.name/fr/post/paris-rail-centrality/index_files/index_4_0.svg&#34; alt=&#34;svg&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;Cela semble correct.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;visualiser-les-résultats&#34;&gt;&#xA;  Visualiser les résultats&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#visualiser-les-r%c3%a9sultats&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Les fonctions proposées par &lt;code&gt;networkx&lt;/code&gt; pour le calcul des mesures de centralité renvoient un dictionnaire dont les clés sont des identifiants de sommet et dont les valeurs sont des scores de centralité. Nous pouvons créer une fonction qui accepte un tel dictionnaire et affiche un diagramme à barres des 25 stations les plus importantes par ordre décroissant de centralité.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;centrality_chart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;centrality_dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;names_and_scores&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node_attributes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;item&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]][&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;node_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;item&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;item&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;centrality_dict&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;items&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;top_25&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;sorted&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;names_and_scores&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;reverse&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)[:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;25&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;top_25_df&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pd&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DataFrame&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;top_25&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;columns&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Station&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Score de centralité&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set_index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Station&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;ax&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;top_25_df&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;plot&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;barh&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;ax&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;invert_yaxis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 class=&#34;heading&#34; id=&#34;la-centralité-de-degré&#34;&gt;&#xA;  La centralité de degré&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#la-centralit%c3%a9-de-degr%c3%a9&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Lisons d&amp;rsquo;abord l&amp;rsquo;intégralité du graphe :&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;nodes&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pd&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read_sql_query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;select * from nodes&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;conn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;index_col&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;node_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;edges&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pd&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read_sql_query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;select * from edges&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;conn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;replace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;conn&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;close&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;from_pandas_edgelist&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;edges&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;source_node_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;target&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;target_node_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;edge_attr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;create_using&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MultiDiGraph&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;node_attributes&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nodes&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;to_dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;orient&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;index&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set_node_attributes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;node_attributes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nodes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; sommets et &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;edges&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; liens chargés.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;563 sommets et 1363 liens chargés.&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;La mesure de centralité la plus simple est la centralité de degré : pour chaque sommet, nous pouvons compter ses liens entrants ou sortants et normaliser le résultat en le divisant par $n - 1$, où $n$ est le nombre de sommets. Dans ce cas présent, les resultats sont les mêmes pour la centralité de degré entrant et la centralité de degré sortant.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;in_degree_centrality_dict&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;in_degree_centrality&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;centrality_chart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;in_degree_centrality_dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Centralité de degré entrant&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;&lt;img src=&#34;https://benjamingeer.name/fr/post/paris-rail-centrality/index_files/index_11_0.svg&#34; alt=&#34;svg&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;On voit tout de suite que les stations ayant les scores le plus élevés sont surtout des stations de métro plutôt que des stations RER. Une explication possible serait la structure apparemment plus radiale du réseau RER par rapport au métro. En plus d&amp;rsquo;être situées sur plusieurs lignes, plusieurs de ces stations (telles que Havre-Caumartin) font partie d&amp;rsquo;un pôle d&amp;rsquo;échange.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;la-centralité-de-vecteur-propre&#34;&gt;&#xA;  La centralité de vecteur propre&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#la-centralit%c3%a9-de-vecteur-propre&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Avec la &lt;a href=&#34;https://fr.wikipedia.org/wiki/Centralit%C3%A9#Centralit%C3%A9_de_vecteur_propre&#34; target=&#34;_blank&#34;&gt;centralité de vecteur propre&lt;/a&gt;, chaque sommet reçoit un score proportionnel à la somme des scores de ses voisins. Un sommet peut ainsi obtenir un score élevé en ayant beaucoup de voisins et/ou en ayant des voisins dont le score est élevé. Dans un graphe non orienté à $n$ sommets, la centralité de vecteur propre $x_i$ d&amp;rsquo;un sommet $i$, dont l&amp;rsquo;ensemble des voisins est $M(i)$, est définie par :&lt;/p&gt;&#xA;$$&#xA;x_i = \frac{1}{\lambda} \sum_{j \in M(i)} x_j&#xA;$$&lt;p&gt;où $\lambda$ est une constante. Nous pouvons écrire cette équation en utilisant la matrice d&amp;rsquo;adjacence $A$ du réseau, dans laquelle $a_{ij}$ est égal à 1 s&amp;rsquo;il y a un lien entre les sommets $i$ et $j$ et à 0 s&amp;rsquo;il n&amp;rsquo;y en a pas :&lt;/p&gt;&#xA;$$&#xA;x_i = \frac{1}{\lambda} \sum_{j = 1}^n a_{ij} x_j&#xA;$$&lt;p&gt;Cela équivaut à :&lt;/p&gt;&#xA;$$&#xA;\mathbf{x} = \frac{1}{\lambda} A\mathbf{x}&#xA;$$&lt;p&gt;où $\mathbf{x}$ est un vecteur dont les éléments sont les scores de centralité. On peut donc écrire :&lt;/p&gt;&#xA;$$&#xA;A\mathbf{x} = \lambda\mathbf{x}&#xA;$$&lt;p&gt;Il s&amp;rsquo;ensuit que $\lambda$ est une valeur propre de $A$ et que $\mathbf{x}$ est le vecteur propre correspondant. Étant donné les valeurs propres et les vecteurs propres de la matrice, il est simple de choisir le vecteur propre pertinent, car (selon le &lt;a href=&#34;https://fr.wikipedia.org/wiki/Th%C3%A9or%C3%A8me_de_Perron-Frobenius&#34; target=&#34;_blank&#34;&gt;théorème de Perron-Frobenius&lt;/a&gt;), pour une matrice (comme la matrice d&amp;rsquo;adjacence) qui n&amp;rsquo;a pas d&amp;rsquo;éléments négatifs, seul le vecteur propre associé à la plus grande valeur propre peut être choisi de façon à ce qu&amp;rsquo;il n&amp;rsquo;ait pas d&amp;rsquo;éléments négatifs. Avec un graphe orienté comme notre réseau de transport, on peut choisir un vecteur propre à gauche ou un vecteur propre à droite. On préfère d&amp;rsquo;habitude le vecteur propre à gauche (et c&amp;rsquo;est ce que fait &lt;code&gt;networkx&lt;/code&gt;), de sorte que le score d&amp;rsquo;un sommet dépend de ses liens entrants plutôt que de ses liens sortants. Cela ne change pas grand-chose dans le cas présent, car presque tous les liens entrants de notre réseau ont un lien sortant correspondant.&lt;/p&gt;&#xA;&lt;p&gt;Lorsque la centralité de vecteur propre est utilisée avec un graphe orienté, celui-ci doit être fortement connexe. C&amp;rsquo;est le cas de notre réseau de transport, car chaque station est accessible depuis toutes les autres :&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_strongly_connected&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;True&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Nous utiliserons ici la fonction &lt;code&gt;networkx.eigenvector_centrality_numpy&lt;/code&gt;, qui construit d&amp;rsquo;abord la matrice d&amp;rsquo;adjacence. Dans un multigraphe orienté comme le nôtre, s&amp;rsquo;il y a $n$ liens allant dans le même sens entre deux sommets, &lt;code&gt;networkx&lt;/code&gt; les représente par la valeur $n$ dans la matrice, ce qui équivaut à un seul lien d&amp;rsquo;intensité $n$. Ensuite il obtient le vecteur propre pertinent et renvoie un dictionnaire qui contient chaque identifiant de sommet et l&amp;rsquo;élément correspondant du vecteur propre.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;eigenvector_centrality_dict&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;eigenvector_centrality_numpy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;centrality_chart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;eigenvector_centrality_dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Centralité de vecteur propre&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;&lt;img src=&#34;https://benjamingeer.name/fr/post/paris-rail-centrality/index_files/index_16_0.svg&#34; alt=&#34;svg&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;Si on compare ces résultats à ceux obtenus pour la centralité de degré, on peut constater que la station Havre-Caumartin, qui se trouve au milieu du pôle d&amp;rsquo;échange Paris Saint-Lazare - Opéra (qui comprend six stations), obtient un score plus élevé parce qu&amp;rsquo;elle est adjacente à deux stations, Saint-Lazare et Opéra, qui ont des scores élevés. Plusieurs autres stations, dont Saint-Augustin, Auber et and Haussmann Saint-Lazare, obtiennent des scores plus élevés pour la même raison.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;la-centralité-dintermédiarité&#34;&gt;&#xA;  La centralité d’intermédiarité&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#la-centralit%c3%a9-dinterm%c3%a9diarit%c3%a9&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;La &lt;a href=&#34;https://fr.wikipedia.org/wiki/Centralit%C3%A9#Centralit%C3%A9_d%27interm%C3%A9diarit%C3%A9&#34; target=&#34;_blank&#34;&gt;centralité d’intermédiarité&lt;/a&gt; compte le nombre de fois où un sommet se trouve sur un des plus courts chemins (c&amp;rsquo;est-à-dire qui traversent le moins de sommets possible) entre chaque paire d&amp;rsquo;autres sommets. Pour un sommet $v$, elle est définie par :&lt;/p&gt;&#xA;$$&#xA;c_B(v) =\sum_{s \neq v \neq t} \frac{\sigma(s, t|v)}{\sigma(s, t)}&#xA;$$&lt;p&gt;où $s$ et $t$ sont n&amp;rsquo;importe quels autres sommets du réseau, $\sigma(s, t)$ est le nombre de plus courts chemins de $s$ à $t$ et $\sigma(s, t|v)$ est le nombre de ces chemins qui passent par $v$. Dans un réseau de transport, un station dont $c_B(v)$ a une valeur élevée est une station par laquelle beaucoup de passagers passeront probablement s&amp;rsquo;ils choissisent un des plus courts chemins menant à leur destination.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;betweenness_centrality_dict&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;betweenness_centrality&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;centrality_chart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;betweenness_centrality_dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Centralité d’intermédiarité&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;&lt;img src=&#34;https://benjamingeer.name/fr/post/paris-rail-centrality/index_files/index_19_0.svg&#34; alt=&#34;svg&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;La plupart des stations figurant sur cette liste sont des stations RER plutôt que des stations de métro, ce qui est logique, car le RER couvre une plus grande distance entre les arrêts. Ainsi, si le même trajet peut être effectué en métro ou en RER, le trajet le plus court sera généralement celui en RER. Il n&amp;rsquo;est pas surprenant de voir Châtelet les Halles en tête de liste, compte tenu de sa situation géographique centrale et du grand nombre de lignes qui passent par son pôle d&amp;rsquo;échange. Il semble qu&amp;rsquo;il y ait aussi d&amp;rsquo;autres configurations qui peuvent donner un score élevé à une station. Par exemple, Juvisy se trouve sur un long tronçon du RER C où il y a peu de correspondances, et elle est reliée à un tronçon semblable du RER D. Il semble donc probable que beaucoup de plus courts chemins doivent passer par cette station.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;conclusion&#34;&gt;&#xA;  Conclusion&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#conclusion&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Ceci n&amp;rsquo;est qu&amp;rsquo;une brève exploration de quelques mesures de centralité pour ce réseau, avec quelques exemples illustrant comment différentes définitions de l&amp;rsquo;importance d&amp;rsquo;un sommet peuvent donner lieu à des scores différents. Tous les scripts utilisés ici se trouvent &lt;a href=&#34;https://framagit.org/benjamingeer/benjamingeer/-/tree/main/notebook-data/paris-rail-data&#34; target=&#34;_blank&#34;&gt;dans le dépôt Git de ce blog&lt;/a&gt;, ainsi que le &lt;a href=&#34;https://framagit.org/benjamingeer/benjamingeer/-/tree/main/notebooks/en/paris-rail-centrality/index.ipynb&#34; target=&#34;_blank&#34;&gt;calepin Jupyter&lt;/a&gt; à partir duquel j&amp;rsquo;ai généré cette page. N&amp;rsquo;hésitez pas à &lt;a href=&#34;https://benjamingeer.name/fr/about/&#34;&gt;me contacter&lt;/a&gt; pour toute question ou suggestion.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Mal partum</title>
      <link>https://benjamingeer.name/fr/post/the-sound-of-crying/</link>
      <pubDate>Thu, 06 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://benjamingeer.name/fr/post/the-sound-of-crying/</guid>
      <description>&lt;p&gt;En 2024 j&amp;rsquo;ai fait les sous-titres anglais du court-métrage &lt;a href=&#34;https://pasfeerique.com/mal-partum&#34; target=&#34;_blank&#34;&gt;&lt;em&gt;Mal partum&lt;/em&gt;&lt;/a&gt;, un beau documentaire sur la dépression post-partum. Émilie D. s&amp;rsquo;est appuyée sur son expérience personnelle pour réaliser un film qui apporte des connaissances pratiques dont nous pouvons tous nous servir.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Shady Lewis, Sur le méridien de Greenwich</title>
      <link>https://benjamingeer.name/fr/post/on-the-greenwich-line/</link>
      <pubDate>Fri, 10 Jan 2025 00:00:00 +0000</pubDate>
      <guid>https://benjamingeer.name/fr/post/on-the-greenwich-line/</guid>
      <description>&lt;p&gt;Le roman &lt;em&gt;Sur le méridien de Greenwich&lt;/em&gt;, de l&amp;rsquo;écrivain égyptien Shady Lewis, est sorti en 2019. Depuis que je l&amp;rsquo;ai lu en arabe en 2023, j&amp;rsquo;ai offert &lt;a href=&#34;https://archive.org/details/20210716_20210716_2223&#34; target=&#34;_blank&#34;&gt;la version arabe originale&lt;/a&gt; ou la &lt;a href=&#34;https://www.actes-sud.fr/sur-le-meridien-de-greenwich&#34; target=&#34;_blank&#34;&gt;traduction française&lt;/a&gt; à plusieurs amis (il y a assi une &lt;a href=&#34;https://hoffmann-und-campe.de/products/63888-auf-dem-nullmeridian&#34; target=&#34;_blank&#34;&gt;traduction allemande&lt;/a&gt;), et je vais maintenant offrir à d&amp;rsquo;autres amis la &lt;a href=&#34;https://www.peirenepress.com/shop/books/on-the-greenwich-line/&#34; target=&#34;_blank&#34;&gt;traduction anglaise&lt;/a&gt; qui sortira le mois prochain. Avec une grande sensibilité, Lewis a écrit un roman comique très drôle sur l&amp;rsquo;immigration, le racisme et la bureaucratie à Londres, où il est travailleur social. Lors d&amp;rsquo;une conférence à l&amp;rsquo;Institut du monde arabe à Paris en avril 2023, il a dit que, lorsque l&amp;rsquo;actualité nous abreuve d&amp;rsquo;horreurs tous les jours au point de nous y habituer, l&amp;rsquo;humour peut raviver nos sentiments. Le traitement m&amp;rsquo;a fait beaucoup de bien.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Sherif Younis, La marche sacrée</title>
      <link>https://benjamingeer.name/fr/post/al-zahf-al-muqaddas/</link>
      <pubDate>Thu, 26 Sep 2024 00:00:00 +0000</pubDate>
      <guid>https://benjamingeer.name/fr/post/al-zahf-al-muqaddas/</guid>
      <description>&lt;p&gt;[Version française du texte publié en espagnol.&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;]&lt;/p&gt;&#xA;&lt;p&gt;Sherif Younis, الزحف المقدس: مظاهرات التنحي وتشكل عبادة ناصر [&lt;em&gt;La marche sacrée : les manifestations contre la démission de Nasser et la formation de son culte&lt;/em&gt;], 1ère édition, Le Caire, Dar Mirit, 2005. 2ème édition revue et corrigée, Beyrouth et Le Caire, Dar al-Tanwir, 2012, 196 pages.&lt;/p&gt;&#xA;&lt;p&gt;En juin 1967, lorsque la dictature militaire égyptienne de Gamal Abdel Nasser a subi une défaite militaire écrasante lors de la guerre des Six Jours contre Israël, le président Nasser a immédiatement annoncé sa démission. Peu après, des foules ont manifesté pendant deux jours dans toute l&amp;rsquo;Égypte pour le supplier de revenir sur cette décision, et Nasser a répondu au tollé en restant en fonction. Dans &lt;em&gt;La Marche sacrée&lt;/em&gt;, l&amp;rsquo;historien égyptien Sherif Younis s&amp;rsquo;interroge sur ce qui a poussé le peuple égyptien à réclamer le maintien de Nasser au pouvoir. Comment un régime autoritaire et impitoyable envers la population, qui exigeait la passivité politique sous peine d&amp;rsquo;emprisonnement et de torture, a-t-il pu susciter une telle ferveur ? Certains historiens du nassérisme soutiennent que ces manifestations répondaient aux émotions sincères des manifestants, alors que d&amp;rsquo;autres pensent qu&amp;rsquo;elles ont été organisées par le régime. Adoptant une approche originale dans l&amp;rsquo;étude du nassérisme, Younis se démarque de ces deux interprétations. Pour lui, les manifestations de soutien au président, sans doute spontanées, étaient aussi un produit de l&amp;rsquo;idéologie que le régime avait mis en place après le coup d&amp;rsquo;État militaire de 1952.&lt;/p&gt;&#xA;&lt;p&gt;Spécialiste de l&amp;rsquo;histoire égyptienne moderne, Younis est l&amp;rsquo;un des historiens égyptiens les plus importants des dernières décennies. Ses recherches reflètent une certaine empreinte foucauldienne. Il a traduit, de l&amp;rsquo;anglais vers l&amp;rsquo;arabe, des classiques comme &lt;em&gt;Metahistory&lt;/em&gt; de Hayden White (1973), ainsi que des travaux fondamentaux sur l&amp;rsquo;histoire égyptienne, comme &lt;em&gt;All the Pasha&amp;rsquo;s Men&lt;/em&gt; de Khaled Fahmy (1997) et &lt;em&gt;Rule of Experts&lt;/em&gt; de Timothy Mitchell (2002). Ses ouvrages et traductions alimentent souvent les débats intellectuels en Égypte et dans le monde arabe en général. Compte tenu de l&amp;rsquo;importance de l&amp;rsquo;auteur, &lt;em&gt;La Marche sacrée&lt;/em&gt; est sans aucun doute une des contributions les plus importantes des dernières décennies aux débats en arabe sur le nassérisme.&lt;/p&gt;&#xA;&lt;p&gt;L&amp;rsquo;historiographie du nassérisme est souvent apologétique ou, dans certains cas, hagiographique, justifiant le régime de Nasser en invoquant son anticolonialisme, son nationalisme arabe ou ses prétendues politiques socialistes. Parfois elle tente d&amp;rsquo;analyser le nassérisme au moyen de théories répandues telles que le marxisme gramscien ou la théorie de la modernisation, sans arriver à expliquer pourquoi ce régime a adopté une forme plutôt qu&amp;rsquo;une autre et pourquoi il a duré près de deux décennies malgré ses échecs répétés. À la différence de ces démarches, l&amp;rsquo;étude de Younis ce concentre sur l&amp;rsquo;idéologie et s&amp;rsquo;attache à analyser les concepts fondamentaux du nassérisme. Grâce à une lecture détaillée de sources primaires (discours officiels, propagande et articles de presse d&amp;rsquo;intellectuels nasséristes entre autres) Younis se démarque des analyses marxistes qui associent le nassérisme à une classe sociale. Il soutient au contraire que la clé de l&amp;rsquo;énigme du régime réside dans le fait qu&amp;rsquo;il ne représentait aucune classe ou groupe particulier en dehors de sa propre élite. Cette élite nassériste était constituée d&amp;rsquo;une petite clique d&amp;rsquo;officiers qui, avec Nasser à leur tête, ont pris le pouvoir en 1952 et mis fin à la domination britannique et à la monarchie égyptienne. Comme l&amp;rsquo;explique Younis, les membres de ce groupe avaient des préférences politiques diverses (islamistes ou communistes, par exemple) et étaient unis par un patriotisme flou et une attirance pour l&amp;rsquo;autoritarisme.&lt;/p&gt;&#xA;&lt;p&gt;L&amp;rsquo;auteur rappelle qu&amp;rsquo;avec la création des Officiers libres en septembre 1949, Nasser et son groupe ont renoncé à tout lien avec les partis et les organisations politiques en Égypte et se sont efforcés de rester strictement indépendants de toutes les forces présentes dans le champ politique. En effet, ils considéraient que l&amp;rsquo;existence même de divisions politiques au sein du peuple égyptien étaient néfaste et profitait aux puissances coloniales. Pour l&amp;rsquo;élite nassériste, il fallait donc avant tout vider l&amp;rsquo;espace public de toute organisation politique qui ne représentait qu&amp;rsquo;une partie du peuple et mettait ainsi la nation en danger. En associant la division à la corruption, le régime se présentait comme un moyen de purifier le peuple. Younis montre que le nassérisme a conçu le peuple comme un ensemble d&amp;rsquo;individus atomisés, qui devaient s&amp;rsquo;aligner derrière Nasser comme dans un défilé militaire. C&amp;rsquo;est ce que le discours officiel appelait la « marche sacrée » : les officiers devaient incarner la conscience et la volonté d&amp;rsquo;un peuple idéal. Selon Younis, dans cette conception « théologique » de la politique, deux sens du terme « peuple » coexistaient : d&amp;rsquo;une part, le peuple idéal et invisible qui, comme un dieu, transmet sa révélation aux officiers de manière directe et inexplicable. D&amp;rsquo;autre part, le peuple réel et présent qui, faible et corrompu, avait besoin d&amp;rsquo;être guidé et transformé en peuple idéal. L&amp;rsquo;idéologie officielle présentait Nasser comme l&amp;rsquo;intermédiaire indispensable entre ces deux phases du peuple, c&amp;rsquo;est-à-dire comme un prophète.&lt;/p&gt;&#xA;&lt;p&gt;Pour Younis, cette conception de Nasser est devenue crédible pour la population surtout grâce à la politique étrangère du régime, qui était attribuée exclusivement au chef et qui visait à réaliser certaines des ambitions du mouvement nationaliste : mettre fin à l&amp;rsquo;humiliation de la colonisation et restaurer la gloire de la patrie. L&amp;rsquo;exemple le plus important de cette politique a été l&amp;rsquo;annonce de la nationalisation du canal de Suez en 1956 et l&amp;rsquo;échec de l&amp;rsquo;invasion israélienne, britannique et française qui l&amp;rsquo;a suivie.&lt;/p&gt;&#xA;&lt;p&gt;Younis montre que l&amp;rsquo;autorité de Nasser reposait sur l&amp;rsquo;idée que seul le chef pouvait maintenir une communication directe avec le peuple. Cette communication avait en théorie des caractéristiques surnaturelles, qui étaient censées rendre superflues les institutions représentatives supprimées par le régime. La passivité politique et la perte des libertés devaient être, pour le peuple égyptien, le prix à payer pour la dignité nationale. Selon Younis, cette idéologie a contribué à créer un sentiment de dépendance au sein de la population, ce qui explique les manifestations contre la démission de Nasser après la défaite contre Israël. Le lien affectif entre les manifestants et Nasser était le résultat du rétrécissement du champ politique imposé par le régime (qui découlait de son rejet du multipartisme), de la réalisation d&amp;rsquo;une partie des revendications du mouvement nationaliste et, enfin, de la diffusion efficace d&amp;rsquo;une théologie officielle fondée sur le culte de Nasser. Ainsi, habitués à l&amp;rsquo;idée que seul Nasser pouvait agir et que leur rôle était celui de simples spectateurs et admirateurs, les manifestants ont exigé que « le seul père qu&amp;rsquo;ils connaissaient » reste en fonction.&lt;/p&gt;&#xA;&lt;p&gt;Younis a continué à élaborer cette analyse dans son livre نداء الشعب: تاريخ نقدي للإيديولوجيا الناصرية [&lt;em&gt;L&amp;rsquo;appel du peuple : histoire critique de l&amp;rsquo;idéologie nassériste&lt;/em&gt;] (754 pages), publié en 2012, dans lequel il examine en détail les racines historiques de cette idéologie ainsi que les institutions et les politiques qui ont contribué à sa diffusion et à son évolution depuis le coup d&amp;rsquo;État de 1952 jusqu&amp;rsquo;à la mort de Nasser en 1970. Mais &lt;em&gt;La Marche sacrée&lt;/em&gt; apporte déjà une contribution importante à la compréhension du nationalisme égyptien et des ressemblances entre le nationalisme et la religion. En particulier, l&amp;rsquo;utilisation de la catégorie de « prophète » pour analyser la domination symbolique exercée par un dictateur perçu comme un « héros national », ainsi que l&amp;rsquo;idée que le nationalisme implique une déification du peuple (ou de la nation), nous incitent à explorer tout un ensemble d&amp;rsquo;outils issus de la sociologie de la religion pour analyser la structure sociale et idéologique du nationalisme, dans le contexte égyptien et au-delà. Ce serait également l&amp;rsquo;occasion de se pencher sur un autre dieu, la « patrie », qui a reçu moins d&amp;rsquo;attention de la part de Younis.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;bibliographie&#34;&gt;&#xA;  Bibliographie&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#bibliographie&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Geer, Benjamin. 2022. “Sherif Younis, Al-zahf al-muqaddas: muzaharat al-tanahhi wa-tashakkul ‘ibadat Nasir [La Marcha Sagrada: las manifestaciones contra la dimisión de Nasser y la formación de su culto].” &lt;em&gt;Prismas. Revista de historia intelectual&lt;/em&gt; 26 (2): 369–70. &lt;a href=&#34;https://doi.org/10.48160/18520499prismas26.1350&#34; target=&#34;_blank&#34;&gt;https://doi.org/10.48160/18520499prismas26.1350&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;Geer, « Sherif Younis, Al-zahf al-muqaddas ».&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</description>
    </item>
    <item>
      <title>Lire la presse avec un pass de la BnF</title>
      <link>https://benjamingeer.name/fr/post/bnf-presse/</link>
      <pubDate>Sat, 21 Sep 2024 00:00:00 +0000</pubDate>
      <guid>https://benjamingeer.name/fr/post/bnf-presse/</guid>
      <description>&lt;p&gt;Beaucoup de titres de presse sont réservés aux abonnés et les abonnements peuvent coûter cher. Pour s&amp;rsquo;informer à moindre coût, on peut acheter un &lt;a href=&#34;https://inscriptionbilletterie.bnf.fr/accueil&#34; target=&#34;_blank&#34;&gt;Pass Lecture/Culture&lt;/a&gt; de la &lt;a href=&#34;https://www.bnf.fr&#34; target=&#34;_blank&#34;&gt;Bibliothèque nationale de France&lt;/a&gt;. Le prix est actuellement 24 € par an, ou 15 € au tarif réduit. Ce pass donne accès à un grand nombre de titres du monde entier, y compris :&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.mediapart.fr/&#34; target=&#34;_blank&#34;&gt;&lt;em&gt;Mediapart&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.alternatives-economiques.fr/&#34; target=&#34;_blank&#34;&gt;&lt;em&gt;Alternatives économiques&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.lemonde.fr/&#34; target=&#34;_blank&#34;&gt;&lt;em&gt;Le Monde&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.liberation.fr/&#34; target=&#34;_blank&#34;&gt;&lt;em&gt;Libération&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.monde-diplomatique.fr/&#34; target=&#34;_blank&#34;&gt;&lt;em&gt;Le Monde diplomatique&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.courrierinternational.com/&#34; target=&#34;_blank&#34;&gt;&lt;em&gt;Courrier international&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.arretsurimages.net/&#34; target=&#34;_blank&#34;&gt;&lt;em&gt;Arrêt sur images&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.nytimes.com/&#34; target=&#34;_blank&#34;&gt;&lt;em&gt;The New York Times&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.wsj.com/&#34; target=&#34;_blank&#34;&gt;&lt;em&gt;The Wall Street Journal&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.economist.com/&#34; target=&#34;_blank&#34;&gt;&lt;em&gt;The Economist&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.tagesspiegel.de/&#34; target=&#34;_blank&#34;&gt;&lt;em&gt;Der Tagesspiegel&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.sueddeutsche.de/&#34; target=&#34;_blank&#34;&gt;&lt;em&gt;Süddeutsche Zeitung&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Voici un petit tutoriel pour en tirer le meilleur parti. En somme, c&amp;rsquo;est moins commode que de s&amp;rsquo;abonner directement à chaque titre, mais ça coûte beaucoup moins cher. Notez bien qu&amp;rsquo;après l&amp;rsquo;achat du pass, il faudra attendre quelques jours pour qu&amp;rsquo;il commence à fonctionner.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;comment-ça-marche&#34;&gt;&#xA;  Comment ça marche&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#comment-%c3%a7a-marche&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Le moyen d&amp;rsquo;accéder aux articles dépend du titre de presse. Il y a plusieurs cas de figure :&lt;/p&gt;&#xA;&lt;h3 class=&#34;heading&#34; id=&#34;lecture-sur-le-site-original&#34;&gt;&#xA;  Lecture sur le site original&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#lecture-sur-le-site-original&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h3&gt;&lt;p&gt;C&amp;rsquo;est possible avec quelques titres :&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;em&gt;Mediapart&lt;/em&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;em&gt;Alternatives économiques&lt;/em&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;em&gt;Arrêt sur images&lt;/em&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;em&gt;The New York Times&lt;/em&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Pour les trois premiers, il suffit de s&amp;rsquo;identifier dans son &lt;a href=&#34;https://espacepersonnel.bnf.fr/&#34; target=&#34;_blank&#34;&gt;Espace personnel BnF&lt;/a&gt; et ensuite de trouver le bon lien qui donne access au site de la publication à travers le serveur de la BnF. Les liens vers &lt;em&gt;Mediapart&lt;/em&gt;, &lt;em&gt;Alternatives économiques&lt;/em&gt;  et &lt;em&gt;Arrêt sur images&lt;/em&gt; se trouvent sur le site &lt;a href=&#34;https://easybnf.fr/&#34; target=&#34;_blank&#34;&gt;easyBnF&lt;/a&gt; (qui n&amp;rsquo;est pas affilié à la BnF).&lt;/p&gt;&#xA;&lt;p&gt;Le cas de &lt;em&gt;The New York Times&lt;/em&gt; est un peu différent. Quand vous visitez &lt;a href=&#34;https://easybnf.fr/&#34; target=&#34;_blank&#34;&gt;easyBnF&lt;/a&gt; et cliquez sur &lt;em&gt;The New York Times&lt;/em&gt;, il faut suivre les instructions affichées. Cela vous permettra de créer rapidement un pass &lt;em&gt;New York Times&lt;/em&gt; gratuit qui vous y donnera accès pendant trois jours. (Récemment cette fonctionnalité d&amp;rsquo;easyBnF semblait être en panne, mais j&amp;rsquo;ai fait la même chose en cherchant le titre du journal dans la &lt;a href=&#34;https://bdl.bnf.fr/bases-de-donnees-par-titre&#34; target=&#34;_blank&#34;&gt;base de données&lt;/a&gt; de la BnF et en suivant les instructions qui s&amp;rsquo;y sont affichées.)&lt;/p&gt;&#xA;&lt;h3 class=&#34;heading&#34; id=&#34;lecture-au-format-pdf-sur-europresse&#34;&gt;&#xA;  Lecture au format PDF sur Europresse&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#lecture-au-format-pdf-sur-europresse&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h3&gt;&lt;p&gt;C&amp;rsquo;est possible pour certains titres, y compris :&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;em&gt;Courrier international&lt;/em&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;em&gt;Le Monde&lt;/em&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;em&gt;Le Monde diplomatique&lt;/em&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;em&gt;Libération&lt;/em&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Le mode d&amp;rsquo;emploi :&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Identifiez-vous dans votre &lt;a href=&#34;https://espacepersonnel.bnf.fr/&#34; target=&#34;_blank&#34;&gt;Espace personnel BnF&lt;/a&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Visitez &lt;a href=&#34;https://easybnf.fr/&#34; target=&#34;_blank&#34;&gt;easyBnF&lt;/a&gt; et cliquez sur Europresse.&lt;/li&gt;&#xA;&lt;li&gt;Cliquez sur &lt;strong&gt;Publications PDF&lt;/strong&gt; et cherchez le titre voulu.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 class=&#34;heading&#34; id=&#34;lecture-sur-le-site-deuropresse&#34;&gt;&#xA;  Lecture sur le site d&amp;rsquo;Europresse&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#lecture-sur-le-site-deuropresse&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h3&gt;&lt;p&gt;Cela vaut entre autres pour :&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;em&gt;Le Monde&lt;/em&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;em&gt;Libération&lt;/em&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;En effet, pour les titres auxquels Europresse donne accès mais qu&amp;rsquo;il ne propose pas au format PDF, il affiche le texte intégral des articles sur son propre site. L&amp;rsquo;inconvénient, c&amp;rsquo;est qu&amp;rsquo;il ne propose aucune navigation et s&amp;rsquo;attend à ce que vous trouviez chaque article en utilisant son moteur de recherche.&lt;/p&gt;&#xA;&lt;p&gt;Sur un ordinateur (avec Firefox ou Chrome) ou sur Android (avec Firefox), je vous conseille d&amp;rsquo;installer plutôt l&amp;rsquo;extension &lt;a href=&#34;https://ophirofox.ophir.dev/&#34; target=&#34;_blank&#34;&gt;Ophirofox&lt;/a&gt; dans votre navigateur. Quand vous naviguez sur le site d&amp;rsquo;un journal compatible, l&amp;rsquo;extension ajoute un bouton &lt;strong&gt;Lire sur Europresse&lt;/strong&gt; sur les articles réservés aux abonnés. En réalité ce bouton ne fait qu&amp;rsquo;ouvrir le site d&amp;rsquo;Europresse, saisir le titre de l&amp;rsquo;article que vous regardiez et lancer la recherche, ce qui fait gagner du temps.&lt;/p&gt;&#xA;&lt;p&gt;Ophirofox n&amp;rsquo;est pas disponible pour iPhone. Dans ce cas-là :&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Copiez le titre de l&amp;rsquo;article.&lt;/li&gt;&#xA;&lt;li&gt;Visitez &lt;a href=&#34;https://easybnf.fr/&#34; target=&#34;_blank&#34;&gt;easyBnF&lt;/a&gt; et cliquez sur Europresse.&lt;/li&gt;&#xA;&lt;li&gt;Cliquez sur &lt;strong&gt;Recherche avancée&lt;/strong&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Collez le titre la où il y a écrit &lt;strong&gt;dans le titre&lt;/strong&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Cliquez sur &lt;strong&gt;Recherche&lt;/strong&gt;.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 class=&#34;heading&#34; id=&#34;lecture-sur-pressreader&#34;&gt;&#xA;  Lecture sur PressReader&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#lecture-sur-pressreader&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h3&gt;&lt;p&gt;Cela vaut entre autres pour :&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;em&gt;The Wall Street Journal&lt;/em&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;em&gt;The Economist&lt;/em&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;em&gt;Süddeutsche Zeitung&lt;/em&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;em&gt;Der Tagesspiegel&lt;/em&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Pour y arriver :&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Sur &lt;a href=&#34;https://easybnf.fr/&#34; target=&#34;_blank&#34;&gt;easyBnF&lt;/a&gt;, cliquez sur &lt;strong&gt;PressReader&lt;/strong&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Cliquez sur &lt;strong&gt;Select Publication&lt;/strong&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Trouvez le titre voulu et cliquez dessus.&lt;/li&gt;&#xA;&lt;li&gt;Cliquez sur une page pour l&amp;rsquo;agrandir.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;Les boutons en bas à gauche permettent d&amp;rsquo;afficher soit chaque page au format PDF, soit le texte des articles.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>كوكبنا</title>
      <link>https://benjamingeer.name/fr/post/kawkabna/</link>
      <pubDate>Fri, 20 Sep 2024 15:00:00 +0000</pubDate>
      <guid>https://benjamingeer.name/fr/post/kawkabna/</guid>
      <description>&lt;p&gt;Un podcast en arabe que j&amp;rsquo;ai commencé en 2021, sur l&amp;rsquo;écologie, la migration et les inégalités, et que j&amp;rsquo;aimerais me remettre à publier un jour : &lt;a href=&#34;https://%d9%83%d9%88%d9%83%d8%a8%d9%86%d8%a7.%d8%b4%d8%a8%d9%83%d8%a9&#34; target=&#34;_blank&#34;&gt;كوكبنا.شبكة&lt;/a&gt;.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Tondauer</title>
      <link>https://benjamingeer.name/fr/post/tondauer/</link>
      <pubDate>Fri, 20 Sep 2024 14:00:00 +0000</pubDate>
      <guid>https://benjamingeer.name/fr/post/tondauer/</guid>
      <description>&lt;p&gt;En 2020 j&amp;rsquo;ai commencé un projet qui s&amp;rsquo;appelle &lt;a href=&#34;https://tondauer.art/fr/&#34; target=&#34;_blank&#34;&gt;Tondauer&lt;/a&gt;, pour faire des éditions de partitions sous licence Creative Commons. C&amp;rsquo;est arrivé à cause du confinement lié au Covid-19 cette année-là. J&amp;rsquo;apprenais à jouer le&#xA;&lt;a href=&#34;https://tondauer.art/fr/2021/03/mendelssohn-prelude-mwv-u-123/&#34; target=&#34;_blank&#34;&gt;Prélude Op. 104a, n° 2 (MSV U 123)&lt;/a&gt; de Felix Mendelssohn, parce qu&amp;rsquo;il convenait bien à mon sentiment de frustration et à mon humeur agitée à l&amp;rsquo;époque.&lt;/p&gt;&#xA;&lt;p&gt;J&amp;rsquo;ai commencé par une édition du XIXe siècle qui pouvait être téléchargée gratuitement. Puis j&amp;rsquo;ai acheté une édition qui proposait des doigtés, et je me suis demandé pourquoi elle avait des notes différentes. J&amp;rsquo;ai cherché sans succès le manuscrit du compositeur, ne trouvant qu&amp;rsquo;un brouillon antérieur. Ayant lu la biographie de Mendelssohn écrite par R. Larry Todd, je lui ai envoyé un mail pour lui demander s&amp;rsquo;il savait où se trouvait le manuscrit de la version finale. Il m&amp;rsquo;a répondu que celui-ci n&amp;rsquo;avait pas été trouvé. Cela signifiait que les seules sources étaient les premières éditions, publiées après la mort du compositeur.&lt;/p&gt;&#xA;&lt;p&gt;En travaillant dans le domaine des humanités numériques, j’avais appris quelque chose sur la façon dont les éditions critiques sont réalisées. J&amp;rsquo;ai donc décidé de faire ma propre édition critique. Pendant plusieurs mois, au fur et à mesure de la réouverture des bibliothèques et des archives, j&amp;rsquo;ai reçu des reproductions numériques des deux premières éditions, une allemande et une britannique. Les deux éditeurs avaient travaillés ensemble pour les publier simultanément, mais elles ne contenaient pas non plus les mêmes notes. Dans mon édition, j&amp;rsquo;ai essayé d&amp;rsquo;expliquer de façon plausible ce qui s&amp;rsquo;était passé et de reconstituer au mieux les intentions du compositeur. Finalement j&amp;rsquo;ai essayé de faire l&amp;rsquo;édition que j&amp;rsquo;aurais voulu avoir, en ajoutant des doigtés grâce à l&amp;rsquo;aide de &lt;a href=&#34;https://www.roskellacademy.com/&#34; target=&#34;_blank&#34;&gt;Penelope Roskell&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Plus récemment, j&amp;rsquo;ai travaillé avec la musicologue Florence Launay sur des éditions d&amp;rsquo;œuvres oubliées de compositrices, en commençant par les &lt;a href=&#34;https://tondauer.art/2022/10/polignac-preludes/&#34; target=&#34;_blank&#34;&gt;Preludes for Piano&lt;/a&gt; d&amp;rsquo;Armande de Polignac. Ces pièces subsistaient uniquement dans un seul exemplaire de la première édition, conservé par les descendants de la compositrice. Florence l&amp;rsquo;avait photocopié et des pianistes avaient enregistré ces pièces en utilisant des photocopies de cette photocopie. Maintenant que nous avons publié une édition corrigée avec la préface de Florence, j&amp;rsquo;espère que d&amp;rsquo;autres pianistes prendront plaisir à jouer ces Préludes.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Ressources sociologiques</title>
      <link>https://benjamingeer.name/fr/post/socioresources/</link>
      <pubDate>Fri, 20 Sep 2024 13:00:00 +0000</pubDate>
      <guid>https://benjamingeer.name/fr/post/socioresources/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://socioresources.net/fr/&#34; target=&#34;_blank&#34;&gt;Mon ancien blog&lt;/a&gt; (2013-2021) sur la sociologie de l&amp;rsquo;autonomie et l&amp;rsquo;autonomie de la sociologie.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>أبحاث لفتت نظري</title>
      <link>https://benjamingeer.name/fr/post/abhath/</link>
      <pubDate>Fri, 20 Sep 2024 12:00:00 +0000</pubDate>
      <guid>https://benjamingeer.name/fr/post/abhath/</guid>
      <description>&lt;p&gt;Mon ancien blog en arabe (2009-2014), sur lequel je résumais des recherches que je trouvais intéressantes : &lt;a href=&#34;https://benjamingeer.blogspot.com/&#34; target=&#34;_blank&#34;&gt;أبحاث لفتت نظري&lt;/a&gt;.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>À propos</title>
      <link>https://benjamingeer.name/fr/about/</link>
      <pubDate>Fri, 20 Sep 2024 00:00:00 +0000</pubDate>
      <guid>https://benjamingeer.name/fr/about/</guid>
      <description>&lt;p&gt;Je suis développeur de logiciels et ancien universitaire (sociologie, histoire&#xA;conceptuelle, linguistique cognitive, culture arabe, humanités numériques).&#xA;J&amp;rsquo;habite en région parisienne.&lt;/p&gt;&#xA;&lt;p&gt;Voici un court essai, écrit en anglais en 2018, sur ma vie professionnelle : &lt;a href=&#34;https://medium.com/sci-five-university-of-basel/an-accidental-career-d09ca45de21a&#34; target=&#34;_blank&#34;&gt;An&#xA;Accidental&#xA;Career&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Un entretien plus détaillé datant de 2017 : &lt;a href=&#34;https://www.opendemocracy.net/en/north-africa-west-asia/surviving-sociology-in-egypt-and-elsewhere/&#34; target=&#34;_blank&#34;&gt;Surviving sociology in Egypt and elsewhere&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;logiciels-libres&#34;&gt;&#xA;  Logiciels libres&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#logiciels-libres&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;&lt;svg aria-hidden=&#34;true&#34; class=&#34;hi-svg-inline&#34; fill=&#34;currentColor&#34; height=&#34;1em&#34; role=&#34;img&#34; style=&#34;color: #2185D0;&#34; viewBox=&#34;0 0 24 24&#34; width=&#34;1em&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;title&gt;Codeberg&lt;/title&gt;&lt;path d=&#34;M11.955.49A12 12 0 0 0 0 12.49a12 12 0 0 0 1.832 6.373L11.838 5.928a.187.14 0 0 1 .324 0l10.006 12.935A12 12 0 0 0 24 12.49a12 12 0 0 0-12-12 12 12 0 0 0-.045 0zm.375 6.467l4.416 16.553a12 12 0 0 0 5.137-4.213z&#34;/&gt;&lt;/svg&gt;&#xA;&#xA;&lt;a href=&#34;https://codeberg.org/benjamingeer&#34; target=&#34;_blank&#34;&gt;Codeberg&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Mes projets actuels de logiciels libres sont sur Codeberg.&lt;/p&gt;&#xA;&lt;p&gt;Le code source de ce site web est &lt;a href=&#34;https://framagit.org/benjamingeer/benjamingeer&#34; target=&#34;_blank&#34;&gt;ici&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;travaux-de-recherche&#34;&gt;&#xA;  Travaux de recherche&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#travaux-de-recherche&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;&lt;svg aria-hidden=&#34;true&#34; class=&#34;hi-svg-inline&#34; fill=&#34;currentColor&#34; height=&#34;1em&#34; role=&#34;img&#34; style=&#34;color: #A6CE39;&#34; viewBox=&#34;0 0 24 24&#34; width=&#34;1em&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;title&gt;ORCID&lt;/title&gt;&lt;path d=&#34;M12 0C5.372 0 0 5.372 0 12s5.372 12 12 12 12-5.372 12-12S18.628 0 12 0zM7.369 4.378c.525 0 .947.431.947.947s-.422.947-.947.947a.95.95 0 0 1-.947-.947c0-.525.422-.947.947-.947zm-.722 3.038h1.444v10.041H6.647V7.416zm3.562 0h3.9c3.712 0 5.344 2.653 5.344 5.025 0 2.578-2.016 5.025-5.325 5.025h-3.919V7.416zm1.444 1.303v7.444h2.297c3.272 0 4.022-2.484 4.022-3.722 0-2.016-1.284-3.722-4.097-3.722h-2.222z&#34;/&gt;&lt;/svg&gt;&#xA; &lt;a href=&#34;https://orcid.org/0000-0002-2449-8558&#34; target=&#34;_blank&#34;&gt;ORCID&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Vous pouvez télécharger toutes mes publications en libre accès sur ma page&#xA;ORCID. Dans certains cas, il faut cliquer sur &lt;strong&gt;Afficher plus de détails&lt;/strong&gt; pour&#xA;afficher l&amp;rsquo;URL de la version en libre accès.&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;contact&#34;&gt;&#xA;  Contact&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#contact&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;&lt;svg aria-hidden=&#34;true&#34; class=&#34;hi-svg-inline&#34; fill=&#34;currentColor&#34; height=&#34;1em&#34; role=&#34;img&#34; style=&#34;color: #3B45FD;&#34; viewBox=&#34;0 0 24 24&#34; width=&#34;1em&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;title&gt;Signal&lt;/title&gt;&lt;path d=&#34;M12 0q-.934 0-1.83.139l.17 1.111a11 11 0 0 1 3.32 0l.172-1.111A12 12 0 0 0 12 0M9.152.34A12 12 0 0 0 5.77 1.742l.584.961a10.8 10.8 0 0 1 3.066-1.27zm5.696 0-.268 1.094a10.8 10.8 0 0 1 3.066 1.27l.584-.962A12 12 0 0 0 14.848.34M12 2.25a9.75 9.75 0 0 0-8.539 14.459c.074.134.1.292.064.441l-1.013 4.338 4.338-1.013a.62.62 0 0 1 .441.064A9.7 9.7 0 0 0 12 21.75c5.385 0 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25m-7.092.068a12 12 0 0 0-2.59 2.59l.909.664a11 11 0 0 1 2.345-2.345zm14.184 0-.664.909a11 11 0 0 1 2.345 2.345l.909-.664a12 12 0 0 0-2.59-2.59M1.742 5.77A12 12 0 0 0 .34 9.152l1.094.268a10.8 10.8 0 0 1 1.269-3.066zm20.516 0-.961.584a10.8 10.8 0 0 1 1.27 3.066l1.093-.268a12 12 0 0 0-1.402-3.383M.138 10.168A12 12 0 0 0 0 12q0 .934.139 1.83l1.111-.17A11 11 0 0 1 1.125 12q0-.848.125-1.66zm23.723.002-1.111.17q.125.812.125 1.66c0 .848-.042 1.12-.125 1.66l1.111.172a12.1 12.1 0 0 0 0-3.662M1.434 14.58l-1.094.268a12 12 0 0 0 .96 2.591l-.265 1.14 1.096.255.36-1.539-.188-.365a10.8 10.8 0 0 1-.87-2.35m21.133 0a10.8 10.8 0 0 1-1.27 3.067l.962.584a12 12 0 0 0 1.402-3.383zm-1.793 3.848a11 11 0 0 1-2.345 2.345l.664.909a12 12 0 0 0 2.59-2.59zm-19.959 1.1L.357 21.48a1.8 1.8 0 0 0 2.162 2.161l1.954-.455-.256-1.095-1.953.455a.675.675 0 0 1-.81-.81l.454-1.954zm16.832 1.769a10.8 10.8 0 0 1-3.066 1.27l.268 1.093a12 12 0 0 0 3.382-1.402zm-10.94.213-1.54.36.256 1.095 1.139-.266c.814.415 1.683.74 2.591.961l.268-1.094a10.8 10.8 0 0 1-2.35-.869zm3.634 1.24-.172 1.111a12.1 12.1 0 0 0 3.662 0l-.17-1.111q-.812.125-1.66.125a11 11 0 0 1-1.66-.125&#34;/&gt;&lt;/svg&gt;&#xA; Signal : &lt;a href=&#34;https://signal.me/#eu/200L01aw3rj2lNCdjUbtZs00I3GGTagyeo0Fy0s0pamNgZSSvNZOvrDu2NAonf6E&#34; target=&#34;_blank&#34;&gt;benjamingeer.11&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;svg aria-hidden=&#34;true&#34; class=&#34;hi-svg-inline&#34; fill=&#34;currentColor&#34; height=&#34;1em&#34; role=&#34;img&#34; viewBox=&#34;0 0 24 24&#34; width=&#34;1em&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;title&gt;Matrix&lt;/title&gt;&lt;path d=&#34;M.632.55v22.9H2.28V24H0V0h2.28v.55zm7.043 7.26v1.157h.033c.309-.443.683-.784 1.117-1.024.433-.245.936-.365 1.5-.365.54 0 1.033.107 1.481.314.448.208.785.582 1.02 1.108.254-.374.6-.706 1.034-.992.434-.287.95-.43 1.546-.43.453 0 .872.056 1.26.167.388.11.716.286.993.53.276.245.489.559.646.951.152.392.23.863.23 1.417v5.728h-2.349V11.52c0-.286-.01-.559-.032-.812a1.755 1.755 0 0 0-.18-.66 1.106 1.106 0 0 0-.438-.448c-.194-.11-.457-.166-.785-.166-.332 0-.6.064-.803.189a1.38 1.38 0 0 0-.48.499 1.946 1.946 0 0 0-.231.696 5.56 5.56 0 0 0-.06.785v4.768h-2.35v-4.8c0-.254-.004-.503-.018-.752a2.074 2.074 0 0 0-.143-.688 1.052 1.052 0 0 0-.415-.503c-.194-.125-.476-.19-.854-.19-.111 0-.259.024-.439.074-.18.051-.36.143-.53.282-.171.138-.319.337-.439.595-.12.259-.18.6-.18 1.02v4.966H5.46V7.81zm15.693 15.64V.55H21.72V0H24v24h-2.28v-.55z&#34;/&gt;&lt;/svg&gt;&#xA; Matrix : &lt;a href=&#34;https://matrix.to/#/@benjamingeer:matrix.org&#34; target=&#34;_blank&#34;&gt;@benjamingeer:matrix.org&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Mail : &lt;a href=&#34;mailto:ben@benjamingeer.name&#34;&gt;ben@benjamingeer.name&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;svg aria-hidden=&#34;true&#34; class=&#34;hi-svg-inline&#34; fill=&#34;currentColor&#34; height=&#34;1em&#34; role=&#34;img&#34; style=&#34;color: #6364FF;&#34; viewBox=&#34;0 0 24 24&#34; width=&#34;1em&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;title&gt;Mastodon&lt;/title&gt;&lt;path d=&#34;M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38.265-.061.527-.132.786-.213.585-.184 1.27-.39 1.774-.753a.057.057 0 0 0 .023-.043v-1.809a.052.052 0 0 0-.02-.041.053.053 0 0 0-.046-.01 20.282 20.282 0 0 1-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.593 5.593 0 0 1-.319-1.433.053.053 0 0 1 .066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422.038-.008.077-.015.11-.024 2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545zm-3.748 9.195h-2.561V8.29c0-1.309-.55-1.976-1.67-1.976-1.23 0-1.846.79-1.846 2.35v3.403h-2.546V8.663c0-1.56-.617-2.35-1.848-2.35-1.112 0-1.668.668-1.67 1.977v6.218H4.822V8.102c0-1.31.337-2.35 1.011-3.12.696-.77 1.608-1.164 2.74-1.164 1.311 0 2.302.5 2.962 1.498l.638 1.06.638-1.06c.66-.999 1.65-1.498 2.96-1.498 1.13 0 2.043.395 2.74 1.164.675.77 1.012 1.81 1.012 3.12z&#34;/&gt;&lt;/svg&gt;&#xA; Mastodon : &lt;a href=&#34;https://piaille.fr/@benjamingeer&#34; target=&#34;_blank&#34;&gt;@benjamingeer@piaille.fr&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Fanny Hensel – Septembre</title>
      <link>https://benjamingeer.name/fr/post/hensel-september/</link>
      <pubDate>Fri, 22 Sep 2023 00:00:00 +0000</pubDate>
      <guid>https://benjamingeer.name/fr/post/hensel-september/</guid>
      <description>&lt;div style=&#34;position: relative; padding-bottom: 56.25%; margin-bottom: 1rem; height: 0; overflow: hidden;&#34;&gt;&#xA;&lt;iframe sandbox=&#34;allow-same-origin allow-scripts allow-popups allow-forms&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34;&#xA;    src=&#34;https://makertube.net/videos/embed/7e2cc234-94af-4e82-8ffe-228b2e0dd02c?title=0&amp;warningTitle=0&amp;peertubeLink=0&#34; title=&#34;Peertube Video&#34; frameborder=&#34;0&#34; allowfullscreen=&#34;&#34;&gt;&lt;/iframe&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;br&gt;&#xA;&lt;p&gt;En 1841, &lt;a href=&#34;https://fr.wikipedia.org/wiki/Fanny_Mendelssohn&#34; target=&#34;_blank&#34;&gt;Fanny Hensel&lt;/a&gt;&#xA;(1805–1847) a écrit &lt;em&gt;Das Jahr&lt;/em&gt; (L&amp;rsquo;année), un&#xA;grand cycle pour piano comprenant un mouvement pour chaque mois de&#xA;l&amp;rsquo;année. Elle a publié « Septembre » en 1846 dans son Op. 2, mais &lt;em&gt;Das&#xA;Jahr&lt;/em&gt; a été publié en entier pour la première fois en 1989. Plus tard,&#xA;un magnifique &lt;a href=&#34;http://resolver.staatsbibliothek-berlin.de/SBB00019D1B00000000&#34; target=&#34;_blank&#34;&gt;manuscrit autographe&#xA;remanié&lt;/a&gt;&#xA;a été trouvé, dans lequel chaque mouvement est copié sur du papier&#xA;d&amp;rsquo;une couleur différente, accompagné d&amp;rsquo;une illustration dessinée par le&#xA;mari de la compositrice, Wilhelm, et précédé d&amp;rsquo;un épigramme poétique.&#xA;Furore Verlag a publié &lt;a href=&#34;https://furore-verlag.de/en/produkt/das-jahr-moderne-notenedition-2/&#34; target=&#34;_blank&#34;&gt;une édition critique&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Pour Marian Wilson Kimber, une considération de la musique, de la&#xA;poésie et des illustrations dans leur ensemble laisse penser que&#xA;l&amp;rsquo;œuvre représente non seulement le cycle de l&amp;rsquo;année, mais aussi les&#xA;étapes de la vie d&amp;rsquo;un individu.&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&lt;p&gt;L&amp;rsquo;épigramme pour « Septembre » vient du poème &lt;a href=&#34;https://de.wikisource.org/wiki/An_den_Mond&#34; target=&#34;_blank&#34;&gt;&lt;em&gt;An den&#xA;Mond&lt;/em&gt;&lt;/a&gt; (À la lune) de&#xA;Goethe :&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Fließe, fließe, lieber Fluß&lt;br&gt;&#xA;Nimmer werd’ ich froh.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;Traduction :&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Coule, coule, chère rivière&lt;br&gt;&#xA;Jamais je ne serai heureux.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;Il y a des interprétations innombrables du poème. Pour Tobias Klein :&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Le repli dans la nature et surtout dans la solitude de la nuit est&#xA;présenté comme une consolation face aux déceptions et aux&#xA;frustrations que l&amp;rsquo;individu rencontre dans la société. &amp;hellip; La&#xA;rivière apparaît dans ce contexte comme un symbole de changement et&#xA;d&amp;rsquo;évanescence, mais aussi d&amp;rsquo;ambivalence, car elle peut être à la&#xA;fois destructrice &amp;hellip; et revigorante &amp;hellip;&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;La pièce présente « une application astucieuse de l&amp;rsquo;effet à trois&#xA;mains », « dans laquelle une mélodie jouée par les pouces dans le&#xA;registre moyen du piano est entourée de notes plus graves et plus&#xA;aigües jouées par les autres doigts, pour créer l&amp;rsquo;illusion de trois&#xA;mains au clavier ».&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; Le harpiste Elias&#xA;Parish-Alvars (1808–1849) a inventé cette technique, le pianiste&#xA;Sigismund Thalberg (1812–1871) l&amp;rsquo;a transférée au piano&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; et&#xA;elle s&amp;rsquo;est répandue dans les années 1830. Dans « Septembre », la voix&#xA;supérieure semble évoquer le courant de la rivière.&lt;/p&gt;&#xA;&lt;p&gt;Le développement harmonique ingénieux du mouvement&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;&#xA;est un exemple de l&amp;rsquo;anticipation chez Hensel de l&amp;rsquo;avant-garde de la&#xA;seconde moitié du XIXe siècle.&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;bibliographie&#34;&gt;&#xA;  Bibliographie&lt;span class=&#34;heading__anchor&#34;&gt; &lt;a href=&#34;#bibliographie&#34;&gt;#&lt;/a&gt;&lt;/span&gt;&#xA;&lt;/h2&gt;&lt;p&gt;Klein, Tobias. n.d. “Interpretation: An den Mond – Johann Wolfgang von Goethe.” &lt;a href=&#34;https://lyrik.antikoerperchen.de/johann-wolfgang-von-goethe-an-den-mond,textbearbeitung,372.html&#34; target=&#34;_blank&#34;&gt;https://lyrik.antikoerperchen.de/johann-wolfgang-von-goethe-an-den-mond,textbearbeitung,372.html&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Manning, Laurence. 2015. “Fanny Hensel, compositrice de l’avenir ? Anticipations du langage musical wagnérien dans l’œuvre pour piano de la maturité de Hensel.” &lt;em&gt;Les Cahiers de la Société québécoise de recherche en musique&lt;/em&gt; 16 (1–2): 121. &lt;a href=&#34;https://doi.org/10.7202/1039618ar&#34; target=&#34;_blank&#34;&gt;https://doi.org/10.7202/1039618ar&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Todd, R. Larry. 2010. &lt;em&gt;Fanny Hensel: The Other Mendelssohn&lt;/em&gt;. Oxford University Press.&lt;/p&gt;&#xA;&lt;p&gt;Walker, Alan. 1987. &lt;em&gt;Franz Liszt: The Virtuoso Years, 1811–1847&lt;/em&gt;. Cornell University Press.&lt;/p&gt;&#xA;&lt;p&gt;Wilson Kimber, Marian. 2008. “Fanny Hensel’s Seasons of Life: Poetic Epigrams, Vignettes, and Meaning in Das Jahr.” &lt;em&gt;Journal of Musicological Research&lt;/em&gt; 27 (4): 359–95. &lt;a href=&#34;https://doi.org/10.1080/01411890802384409&#34; target=&#34;_blank&#34;&gt;https://doi.org/10.1080/01411890802384409&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;Kimber, « Fanny Hensel&amp;rsquo;s Seasons of Life ».&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;Klein, « Interpretation: An den Mond ».&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:3&#34;&gt;&#xA;&lt;p&gt;Todd, &lt;em&gt;Fanny Hensel&lt;/em&gt;, 264, 233.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:4&#34;&gt;&#xA;&lt;p&gt;Walker, &lt;em&gt;Franz Liszt&lt;/em&gt;, 234.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:5&#34;&gt;&#xA;&lt;p&gt;Todd, &lt;em&gt;Fanny Hensel&lt;/em&gt;, 275–77.&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:6&#34;&gt;&#xA;&lt;p&gt;Manning, « Fanny Hensel, compositrice de l’avenir ».&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</description>
    </item>
    <item>
      <title>Chopin, Valse, op. 64, n° 2</title>
      <link>https://benjamingeer.name/fr/post/chopin-waltz/</link>
      <pubDate>Sat, 20 May 2023 00:00:00 +0000</pubDate>
      <guid>https://benjamingeer.name/fr/post/chopin-waltz/</guid>
      <description>&lt;div style=&#34;position: relative; padding-bottom: 56.25%; margin-bottom: 1rem; height: 0; overflow: hidden;&#34;&gt;&#xA;&lt;iframe sandbox=&#34;allow-same-origin allow-scripts allow-popups allow-forms&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34;&#xA;    src=&#34;https://makertube.net/videos/embed/4d42551a-74b8-454b-a429-2e87807c2f59?title=0&amp;warningTitle=0&amp;peertubeLink=0&#34; title=&#34;Peertube Video&#34; frameborder=&#34;0&#34; allowfullscreen=&#34;&#34;&gt;&lt;/iframe&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;br&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://fr.wikipedia.org/wiki/Valse,_opus_64_no_2_de_Chopin&#34; target=&#34;_blank&#34;&gt;Frédéric Chopin, Valse, op. 64 n° 2&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Benjamin Geer, piano.&lt;/p&gt;&#xA;&lt;p&gt;Enregistrée le 20 mai 2023.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>J. S. Bach, tr. Busoni – Ich ruf’ zu dir, Herr</title>
      <link>https://benjamingeer.name/fr/post/bach-busoni/</link>
      <pubDate>Sun, 19 Sep 2021 00:00:00 +0000</pubDate>
      <guid>https://benjamingeer.name/fr/post/bach-busoni/</guid>
      <description>&lt;iframe&#xA;  src=&#34;https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/1127316505&amp;color=%23ff5500&amp;auto_play=false&amp;hide_related=false&amp;show_comments=true&amp;show_user=true&amp;show_reposts=false&amp;show_teaser=true&#34;&#xA;  width=&#34;100%&#34;&#xA;  height=&#34;166&#34;&#xA;  frameborder=&#34;no&#34;&#xA;  scrolling=&#34;no&#34;&gt;&lt;/iframe&gt;&#xA;&#xA;&lt;br&gt;&#xA;&lt;p&gt;J. S. Bach, &lt;a href=&#34;https://www.bachvereniging.nl/en/bwv/bwv-639/&#34; target=&#34;_blank&#34;&gt;Ich ruf’ zu dir,&#xA;Herr&lt;/a&gt;, transcription de&#xA;&lt;a href=&#34;https://fr.wikipedia.org/wiki/Ferruccio_Busoni&#34; target=&#34;_blank&#34;&gt;Ferruccio Busoni&lt;/a&gt;&#xA;pour le piano.&lt;/p&gt;&#xA;&lt;p&gt;Benjamin Geer, piano.&lt;/p&gt;&#xA;&lt;p&gt;Enregistré le 8 juillet 2021.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>J’ai essayé d’être guitariste de jazz</title>
      <link>https://benjamingeer.name/fr/post/jazz-guitarist/</link>
      <pubDate>Sun, 11 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://benjamingeer.name/fr/post/jazz-guitarist/</guid>
      <description>&lt;p&gt;J&amp;rsquo;ai commencé à jouer de la guitare de jazz à peu près au moment&#xA;d&amp;rsquo;aller à l&amp;rsquo;université. Je voulais allier la tradition d&amp;rsquo;improvisation&#xA;du jazz à l&amp;rsquo;harmonie non-tonale et des structures à grande échelle.&#xA;Mais je pensais qu&amp;rsquo;il fallait commencer par le bebop.&lt;/p&gt;&#xA;&lt;p&gt;En 1995–96, alors que je travaillais comme assistant d&amp;rsquo;anglais en&#xA;France, j&amp;rsquo;ai pu jouer dans un orchestre de jazz ainsi que dans un&#xA;quintette :&lt;/p&gt;&#xA;&lt;iframe&#xA;  src=&#34;https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/459924804&amp;color=%23ff5500&amp;auto_play=false&amp;hide_related=false&amp;show_comments=true&amp;show_user=true&amp;show_reposts=false&amp;show_teaser=true&#34;&#xA;  width=&#34;100%&#34;&#xA;  height=&#34;166&#34;&#xA;  frameborder=&#34;no&#34;&#xA;  scrolling=&#34;no&#34;&gt;&lt;/iframe&gt;&#xA;&#xA;&lt;p&gt;Voici des enregistrements antérieurs qui datent de 1991 :&lt;/p&gt;&#xA;&lt;iframe&#xA;  src=&#34;https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/459910407&amp;color=%23ff5500&amp;auto_play=false&amp;hide_related=false&amp;show_comments=true&amp;show_user=true&amp;show_reposts=false&amp;show_teaser=true&#34;&#xA;  width=&#34;100%&#34;&#xA;  height=&#34;166&#34;&#xA;  frameborder=&#34;no&#34;&#xA;  scrolling=&#34;no&#34;&gt;&lt;/iframe&gt;&#xA;&#xA;&lt;iframe&#xA;  src=&#34;https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/459916443&amp;color=%23ff5500&amp;auto_play=false&amp;hide_related=false&amp;show_comments=true&amp;show_user=true&amp;show_reposts=false&amp;show_teaser=true&#34;&#xA;  width=&#34;100%&#34;&#xA;  height=&#34;166&#34;&#xA;  frameborder=&#34;no&#34;&#xA;  scrolling=&#34;no&#34;&gt;&lt;/iframe&gt;&#xA;&#xA;&lt;p&gt;À l&amp;rsquo;age de 30 ans environ j&amp;rsquo;ai arrêté de jouer, surtout parce que&#xA;j&amp;rsquo;étais frustré par la lenteur de mes progrès ainsi que par la&#xA;difficulté de concilier la musique et la nécessité de gagner ma vie en&#xA;faisant autre chose. Je regrette de ne pas avoir continué.&lt;/p&gt;&#xA;</description>
    </item>
  </channel>
</rss>
