{"id":3828,"date":"2013-05-30T14:59:08","date_gmt":"2013-05-30T13:59:08","guid":{"rendered":"http:\/\/blog.capdata.fr\/?p=3828"},"modified":"2022-11-21T17:02:28","modified_gmt":"2022-11-21T16:02:28","slug":"parallelisme","status":"publish","type":"post","link":"https:\/\/blog.capdata.fr\/index.php\/parallelisme\/","title":{"rendered":"Parall\u00e9lisme"},"content":{"rendered":"<a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-twitter nolightbox\" data-provider=\"twitter\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Twitter\" href=\"https:\/\/twitter.com\/intent\/tweet?url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F3828&#038;text=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"twitter\" title=\"Share on Twitter\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/twitter.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-linkedin nolightbox\" data-provider=\"linkedin\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Linkedin\" href=\"https:\/\/www.linkedin.com\/shareArticle?mini=true&#038;url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F3828&#038;title=Parall%C3%A9lisme\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"linkedin\" title=\"Share on Linkedin\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/linkedin.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-mail nolightbox\" data-provider=\"mail\" rel=\"nofollow\" title=\"Share by email\" href=\"mailto:?subject=Parall%C3%A9lisme&#038;body=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20:%20https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F3828\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"mail\" title=\"Share by email\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/mail.png\" \/><\/a><p>Un post assez condens\u00e9 pour rappeler les \u00e9l\u00e9ments cl\u00e9s \u00e0 garder \u00e0 l&#8217;esprit lorsque l&#8217;on parle de parall\u00e9lisme sur SQL Server. Il suppose que vous soyez familiers du concept. Si ce n&#8217;est pas le cas, la visite commence par <a href=\"https:\/\/www.simple-talk.com\/sql\/learn-sql-server\/understanding-and-using-parallelism-in-sql-server\/\">cet excellent article <\/a>en anglais de Paul White sur simple-talk, ou en fran\u00e7ais sur <a href=\"https:\/\/msdn.microsoft.com\/fr-fr\/library\/ms178065%28v=sql.105%29.aspx\">MSDN<\/a>.<\/p>\n<h2>Quelques d\u00e9finitions d&#8217;abord:<\/h2>\n<ul>\n<li><strong>Trivial Plan<\/strong>: un plan d&#8217;ex\u00e9cution est consid\u00e9r\u00e9 comme trivial lorsqu&#8217;il n&#8217;y a pas d&#8217;alternative possible. Par exemple SELECT COL1, COL2 FROM TABLE.<\/li>\n<\/ul>\n<ul>\n<li><strong>Serial Zone<\/strong>: C&#8217;est un ensemble de conditions qui font qu&#8217;un plan parall\u00e8le n&#8217;est pas applicable.<\/li>\n<\/ul>\n<p>Parmi ces conditions on trouve <em>(1)<\/em>:<\/p>\n<ol>\n<li>Modification d&#8217;une variable table.<\/li>\n<li>Utilisation d&#8217;une fonction TSQL ou CLR scalaire. La fonction CLR doit utiliser InitMethod() d\u00e9finie avec DataAccess (<a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/ms131109.aspx\">https:\/\/msdn.microsoft.com\/en-us\/library\/ms131109.aspx<\/a>) .<\/li>\n<li>Quelques fonctions builtin OBJECT_NAME() \/ OBJECT_ID(), ENCRYPTBYCERT(), ERROR_NUMBER(), @@TRANCOUNT&#8230;<\/li>\n<li>Curseurs dynamiques<\/li>\n<li>Table scan d&#8217;objets syst\u00e8me<\/li>\n<li>Backward scan<\/li>\n<li>Utilisation d&#8217;un Global Scalar Aggregate<\/li>\n<li>Requ\u00eates r\u00e9cursives<\/li>\n<li>TOP<\/li>\n<li>Utilisation d&#8217;une TVF<\/li>\n<li>Et potentiellement d&#8217;autres&#8230;<\/li>\n<\/ol>\n<p>Depuis SQL Server 2012, un attribut <em>NonParallelPlanReason<\/em> est ajout\u00e9 dans le plan XML, qui indique pourquoi le plan n&#8217;a pas pu \u00eatre parall\u00e9lis\u00e9. Voir le <a href=\"https:\/\/www.sqlskills.com\/blogs\/joe\/sql-server-2012-execution-plans-nonparallelplanreason\/\">post <\/a>de Joe Sack \u00e0 ce sujet.<\/p>\n<h2>Dans quelles conditions un plan est-il parall\u00e9lis\u00e9 ?<\/h2>\n<p>Lorsque le plan optimal est trouv\u00e9 pour une requ\u00eate, et si les conditions sont favorables (le plan n&#8217;est pas trivial, pas de serial zone, le masque CPU pr\u00e9sente au moins 2 CPU, MAXDOP est diff\u00e9rent de 1, etc&#8230;), son co\u00fbt est compar\u00e9 \u00e0 la valeur du param\u00e8tre &#8216;Cost Threshold for Parallelism&#8217;. Ce param\u00e8tre repr\u00e9sente un seuil de temps estim\u00e9 en secondes pour ex\u00e9cuter un plan s\u00e9rialis\u00e9 (sur un seul processeur), par d\u00e9faut 5 secondes. Si le co\u00fbt du plan retenu est sup\u00e9rieur \u00e0 cette valeur, alors l&#8217;optimiseur va \u00e9valuer un plan parall\u00e8le. Ci-dessous, une requ\u00eate sur AdventureWorks2012, un plan avec un co\u00fbt de 124.08, et un DOP de 4 \u00e0 l&#8217;ex\u00e9cution:<\/p>\n<p><a href=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/parallel_cost1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4324\" title=\"parallel_cost\" src=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/parallel_cost1.png\" alt=\"\" width=\"278\" height=\"312\" srcset=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/parallel_cost1.png 278w, https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/parallel_cost1-267x300.png 267w\" sizes=\"auto, (max-width: 278px) 100vw, 278px\" \/><\/a><\/p>\n<p>En fait la formulation <em>plan parall\u00e8le<\/em> n&#8217;est pas tout \u00e0 fait exacte, dans la mesure o\u00f9 seulement une poign\u00e9e d&#8217;op\u00e9rateurs physiques sont r\u00e9ellement &#8216;<em>parallel-aware<\/em>&#8216;, et m\u00eame parmi ceux-ci, tr\u00e8s peu sont structur\u00e9s pour g\u00e9rer le parall\u00e9lisme et impl\u00e9mentent des producteurs et des consommateurs de lignes: principalement les op\u00e9rateurs Exchange (Gather, Distribute et Repartition). Les autres (Stream Aggregate, Merge Join et Sort dans l&#8217;exemple) seront simplement dupliqu\u00e9s \u00e0 hauteur du DOP par l&#8217;op\u00e9rateur parent (Repartition et Gather dans l&#8217;exemple):<\/p>\n<p><a href=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/parallel_plan_1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4328\" title=\"parallel_plan_1\" src=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/parallel_plan_1.png\" alt=\"\" width=\"1292\" height=\"232\" srcset=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/parallel_plan_1.png 1292w, https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/parallel_plan_1-300x53.png 300w, https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/parallel_plan_1-768x138.png 768w, https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/parallel_plan_1-1024x183.png 1024w\" sizes=\"auto, (max-width: 1292px) 100vw, 1292px\" \/><\/a>En s\u00e9lectionnant l&#8217;op\u00e9rateur dans le plan XML, et en pressant F4, on obtient des infos sur les conditions de r\u00e9partition des lignes par thread, par exemple l&#8217;Index Scan sur bigTransactionHistory:<\/p>\n<p><a href=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/maxdop_details.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4340\" title=\"maxdop_details\" src=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/maxdop_details.png\" alt=\"\" width=\"311\" height=\"367\" srcset=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/maxdop_details.png 311w, https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/maxdop_details-254x300.png 254w\" sizes=\"auto, (max-width: 311px) 100vw, 311px\" \/><\/a><\/p>\n<p>Le Parallel Page Supplier est un op\u00e9rateur de distribution de lignes qui se place en amont de l&#8217;index scan (et qui ne se voit pas dans un plan XML). Dans le cas ci-dessus il ne r\u00e9partit pas uniform\u00e9ment le nombre de lignes \u00e0 lire par worker. Les workers 1 et 4 vont traiter 90000+ lignes alors que les workers 2 et 3 vont en\u00a0traiter davantage. Ceci est du aux conditions de charge des schedulers au moment de l&#8217;ex\u00e9cution. L&#8217;id\u00e9e est que les canaux les moins encombr\u00e9s demandent plus de lignes au PPS, mais comme c&#8217;est empirique, en sortie de l&#8217;op\u00e9rateur certains workers auront termin\u00e9 leur t\u00e2che avant les autres, et vont devoir attendre (sur CXPACKET).<\/p>\n<p>A noter que le worker not\u00e9 <em>Thread 0<\/em> est le consommateur en bout de cha\u00eene. Son travail est de rassembler les lignes produites par les 4 workers. Il aura toujours 0 lignes affect\u00e9es.<\/p>\n<h2>La d\u00e9tection globale<\/h2>\n<p>En r\u00e8gle g\u00e9n\u00e9rale, le parall\u00e9lisme est une bonne chose. Il permet de maximiser l&#8217;utilisation des ressources CPU pour une requ\u00eate donn\u00e9e. Mais il peut \u00eatre aussi le sympt\u00f4me d&#8217;un probl\u00e8me de performance SQL sur l&#8217;instance, et d&#8217;une mauvaise configuration de MAXDOP (par d\u00e9faut). En raison du manque d&#8217;index ou de couverture des indexes (ORM &amp; Cie), ou d&#8217;un probl\u00e8me d&#8217;\u00e9criture ou de stats, le co\u00fbt de la plupart des requ\u00eates peut \u00eatre tr\u00e8s \u00e9lev\u00e9 et d\u00e9passer CTFP, et dans ce cas les requ\u00eates concern\u00e9es vont parall\u00e9liser. On rappelle que le degr\u00e9 de parall\u00e9lisme est appliqu\u00e9 \u00e0 chaque entr\u00e9e et sortie de chaque op\u00e9rateur parallel-aware. Donc avec un plan profond comme le gouffre de Padirac sur une machine 64 procs, \u00e7a peut faire pas mal de workers monopolis\u00e9s.<\/p>\n<p>Si vous avez assist\u00e9 <a href=\"https:\/\/blog.capdata.fr\/index.php\/journees-sql-server-2012\/\">\u00e0 notre d\u00e9mo<\/a> aux journ\u00e9es SQL en d\u00e9cembre dernier, vous savez comment d\u00e9tecter ce genre de situation: les waits. On peut d\u00e9terminer les attentes principales gr\u00e2ce \u00e0 la requ\u00eate de <a href=\"https:\/\/www.sqlskills.com\/blogs\/glenn\/\">Glenn Berry <\/a>\u00e0 laquelle j&#8217;ai ajout\u00e9 les 3 derni\u00e8res exclusions pour SQL 2012 (SP_SERVER_DIAGNOSTICS_SLEEP est notamment visible sur les clusters):<\/p>\n<pre name=\"code\" class=\"sql\">WITH Waits AS\r\n(SELECT wait_type, wait_time_ms \/ 1000. AS wait_time_s,\r\n100. * wait_time_ms \/ SUM(wait_time_ms) OVER() AS pct,\r\nROW_NUMBER() OVER(ORDER BY wait_time_ms DESC) AS rn\r\nFROM sys.dm_os_wait_stats\r\nWHERE wait_type NOT IN ('CLR_SEMAPHORE','LAZYWRITER_SLEEP','RESOURCE_QUEUE','SLEEP_TASK',\r\n'SLEEP_SYSTEMTASK','SQLTRACE_BUFFER_FLUSH','WAITFOR', 'LOGMGR_QUEUE','CHECKPOINT_QUEUE',\r\n'REQUEST_FOR_DEADLOCK_SEARCH','XE_TIMER_EVENT','BROKER_TO_FLUSH','BROKER_TASK_STOP','CLR_MANUAL_EVENT',\r\n'CLR_AUTO_EVENT','DISPATCHER_QUEUE_SEMAPHORE', 'FT_IFTS_SCHEDULER_IDLE_WAIT',\r\n'XE_DISPATCHER_WAIT', 'XE_DISPATCHER_JOIN', 'SQLTRACE_INCREMENTAL_FLUSH_SLEEP',\r\n'ONDEMAND_TASK_QUEUE', 'BROKER_EVENTHANDLER', 'SLEEP_BPOOL_FLUSH','SP_SERVER_DIAGNOSTICS_SLEEP',\r\n'HADR_FILESTREAM_IOMGR_IOCOMPLETION','DIRTY_PAGE_POLL'))\r\nSELECT W1.wait_type, \r\nCAST(W1.wait_time_s AS DECIMAL(12, 2)) AS wait_time_s,\r\nCAST(W1.pct AS DECIMAL(12, 2)) AS pct,\r\nCAST(SUM(W2.pct) AS DECIMAL(12, 2)) AS running_pct\r\nFROM Waits AS W1\r\nINNER JOIN Waits AS W2\r\nON W2.rn &lt; = W1.rn\r\nGROUP BY W1.rn, W1.wait_type, W1.wait_time_s, W1.pct\r\nHAVING SUM(W2.pct) - W1.pct &lt; 99 OPTION (RECOMPILE);<\/pre>\n<p><a href=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/CXPACKET_waits.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4332\" title=\"CXPACKET_waits\" src=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/CXPACKET_waits.png\" alt=\"\" width=\"399\" height=\"306\" srcset=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/CXPACKET_waits.png 399w, https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/CXPACKET_waits-300x230.png 300w\" sizes=\"auto, (max-width: 399px) 100vw, 399px\" \/><\/a><\/p>\n<p>Sur la plupart des syst\u00e8mes que l&#8217;on audite en conseil, il est plut\u00f4t rare de ne pas trouver CXPACKET en premier dans le top des waits. Ca ne veut pas dire grand chose en soi, simplement que des plans sont ex\u00e9cut\u00e9s en parall\u00e8le, et dans ce cas il est normal de voir du CXPACKET comme on l&#8217;a vu plus haut. Souvent il est accompagn\u00e9 d&#8217;un autre wait, par exemple PAGEIOLATCH_%. Dans ce cas, le probl\u00e8me de fond se trouve sur le disque. On lit trop de donn\u00e9es, ou le disque ne r\u00e9pond pas assez vite. Et donc l&#8217;attente qui se trouve derri\u00e8re la lecture (CXPACKET dans un plan parall\u00e8le) attend \u00e0 son tour plus longtemps.<\/p>\n<p>Donc la r\u00e9ponse se trouvera quelque part dans sys.dm_exec_query_stats, en triant sur total_worker_time, et en affichant le plan associ\u00e9. J&#8217;utilise tr\u00e8s souvent cette requ\u00eate sur les audits:<\/p>\n<pre name=\"code\" class=\"sql\">select top 20 S.text 'SQLtext', STAT.execution_count 'Plan reuse (total executions)', STAT.plan_generation_num 'Plans generations', \r\nSTAT.creation_time 'Last compile time',STAT.last_execution_time 'Last execution time',\r\nSTAT.total_worker_time\/1000 'Total CPU time (ms)', STAT.total_worker_time\/1000\/STAT.execution_count 'CPU time\/exec (ms)',\r\nSTAT.total_elapsed_time\/1000 'Total Elapsed (ms)',  STAT.total_elapsed_time\/1000\/STAT.execution_count 'Total Elapsed\/exec (ms)',\r\nSTAT.total_logical_reads 'Total Logical Reads', STAT.total_logical_reads\/STAT.execution_count 'Logical Reads\/exec', \r\nSTAT.total_logical_writes 'Total Logical Writes', STAT.total_logical_writes\/STAT.execution_count 'Logical Writes\/exec', \r\nP.query_plan 'Last query Plan'\r\nfrom sys.dm_exec_query_stats STAT with (NOLOCK)\r\ncross apply sys.dm_exec_sql_text(STAT.sql_handle) S\r\ncross apply sys.dm_exec_query_plan(STAT.plan_handle) P\r\norder by STAT.total_worker_time\/1000 desc;\r\nGO<\/pre>\n<p>Evidemment si l&#8217;instance n&#8217;est d\u00e9marr\u00e9e que depuis 24 heures \u00e7a ne va pas \u00eatre forc\u00e9ment tr\u00e8s int\u00e9ressant. Mais \u00e7a permet de trier les requ\u00eates par utilisation CPU, de voir combien de fois le plan a \u00e9t\u00e9 r\u00e9utilis\u00e9, quel temps de r\u00e9ponse par ex\u00e9cution, etc&#8230; Et surtout son co\u00fbt et s&#8217;il a \u00e9t\u00e9 parall\u00e9lis\u00e9.<\/p>\n<p>Le cercle vertueux de l&#8217;analyse de performance d\u00e9bute comme \u00e7a: on regarde les attentes, on regarde les requ\u00eates les plus consonmmatrices, et s&#8217;attaque \u00e0 la premi\u00e8re, on r\u00e9sout le probl\u00e8me, on regarde les attentes \u00e0 nouveau , etc&#8230;<\/p>\n<h2>Degr\u00e9 de parall\u00e9lisme:<\/h2>\n<p>Le degr\u00e9 de parall\u00e9lisme repr\u00e9sente dans un plan parall\u00e9lis\u00e9 le nombre de workers impliqu\u00e9s de chaque c\u00f4t\u00e9 de chaque op\u00e9rateur parallel-aware. Donc \u00e7a ne repr\u00e9sente pas du tout le nombre total de workers dans un plan (sauf dans le cas d&#8217;un op\u00e9rateur parall\u00e8le unique) (2).<\/p>\n<p>D&#8217;ailleurs la valeur de MAXDOP ne sera pas forc\u00e9ment appliqu\u00e9e, comme son nom l&#8217;indique, c&#8217;est un MAX. Autre \u00e9l\u00e9ment tr\u00e8s important, un plan parall\u00e8le est compil\u00e9 et mis dans le plan cache, mais la valeur du DOP ne sera \u00e9tablie qu&#8217;au runtime en fonction de divers param\u00e8tres: le param\u00e8tre serveur <em>&#8216;max degree of parallelism&#8217;<\/em>, la pr\u00e9sence d&#8217;un hint, d&#8217;un plan guide ou d&#8217;un groupe de ressources RG modifiant la valeur de MAXDOP pour la requ\u00eate, le nombre de schedulers visibles et le nombre de workers disponibles dans le pool.<\/p>\n<p>Par d\u00e9faut la valeur du param\u00e8tre &#8216;max degree of parallelism&#8217; est fix\u00e9e \u00e0 0, ce qui signifie que MAXDOP sera \u00e9gal au nombre de schedulers visibles dans le masque CPU. Le masque CPU (CPU Affinity mask) prenant lui-m\u00eame par d\u00e9faut tous les CPU visibles, on peut donc dire pour raccourcir que souvent MAXDOP = nombre de procs.<\/p>\n<p>Sur les machines avec de nombreux CPU, on va trouver de tr\u00e8s nombreux workers dans un plan parall\u00e8le, et plus il va y en avoir, plus il va y avoir d&#8217;attentes sur CXPACKET. Et c&#8217;est l\u00e0 que les mauvaises langues se d\u00e9lient sur le net: la solution miracle serait, lit-on partout, de mettre MAXDOP=1 au niveau de l&#8217;instance, ce qui revient \u00e0 ne plus compiler que des plans s\u00e9rialis\u00e9s&#8230; \ud83d\ude41<\/p>\n<h2>Avant de toucher \u00e0 MAXDOP&#8230;<\/h2>\n<p>Ce qu&#8217;il faut bien comprendre, c&#8217;est qu&#8217;un plan est parall\u00e9lis\u00e9 parce que son co\u00fbt est plus \u00e9lev\u00e9 que CTFP. Donc la racine du probl\u00e8me, c&#8217;est le co\u00fbt, pas le parral\u00e9lisme. En r\u00e9\u00e9crivant la requ\u00eate, en pla\u00e7ant un index judicieux, on peut faire baisser le co\u00fbt de mani\u00e8re dramatique.<\/p>\n<p>Si on reprend notre requ\u00eate sur AdventureWorks2012, en pla\u00e7ant un index sur bigTransactionHistory (Quantity) include (ProductID), on peut faire baisser le co\u00fbt de 84%:<\/p>\n<p><a href=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/cheapplan.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4351\" title=\"cheapplan\" src=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/cheapplan.png\" alt=\"\" width=\"278\" height=\"340\" srcset=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/cheapplan.png 278w, https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/cheapplan-245x300.png 245w\" sizes=\"auto, (max-width: 278px) 100vw, 278px\" \/><\/a><\/p>\n<p>Ca passe au millim\u00e8tre mais surtout j&#8217;ai diminu\u00e9 la charge sur l&#8217;instance en IO et en CPU, sans toucher \u00e0 aucun param\u00e8tre MAXDOP \/ CTFP. C&#8217;est donc un premier axe d&#8217;am\u00e9lioration: s&#8217;occuper de la cause racine du probl\u00e8me en priorit\u00e9.<\/p>\n<h2>Abaisser la valeur de MAXDOP:<\/h2>\n<p>Cel\u00e0 dit, plus il y a de donn\u00e9es, et plus il est difficile de faire baisser les co\u00fbts malgr\u00e9 tout. Dans l&#8217;absolu, l&#8217;\u00e9diteur pr\u00e9conise de limiter la valeur de &#8216;max degree of parallellism&#8217; \u00e0 8 dans le cas d&#8217;une machine non-NUMA de plus de 8 CPU, et au nombre de NUMA nodes dans le cas d&#8217;une machine NUMA. Si l&#8217;hyperthreading est activ\u00e9, on ne tiendra compte que des cores physiques. (3)<\/p>\n<h2>Bitmap filtering:<\/h2>\n<p>Le Bitmap Filter (4) est un op\u00e9rateur utilis\u00e9 \u00e0 la fois dans les plans s\u00e9rialis\u00e9s (dans un Hash Match) et les plans parall\u00e8les. Mais en fait il n&#8217;est r\u00e9ellement visible que dans les plans parall\u00e8les:<\/p>\n<p><a href=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/Bitmapexample1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4378\" title=\"Bitmapexample1\" src=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/Bitmapexample1.png\" alt=\"\" width=\"662\" height=\"166\" srcset=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/Bitmapexample1.png 662w, https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/Bitmapexample1-300x75.png 300w\" sizes=\"auto, (max-width: 662px) 100vw, 662px\" \/><\/a><\/p>\n<p>Le but du Bitmap filter est de filtrer le plus t\u00f4t possible les lignes arrivant des op\u00e9rateurs en dessous dans l&#8217;ex\u00e9cution. Il est beaucoup utilis\u00e9 conjointement avec des jointures Hash Match en parall\u00e8le comme c&#8217;est le cas ici. Lors de la phase de probe, le Bitmap permet de filtrer les lignes qui ne pourront pas \u00eatre jointes de toute mani\u00e8re avec la table de Build.<\/p>\n<p>Parfois le Bitmap peut \u00eatre appliqu\u00e9 encore plus en amont dans le plan, par exemple sur un Table Scan ou Index Scan\/Seek, dans ce cas l&#8217;op\u00e9rateur sur lequel il est appliqu\u00e9 montre un attribut INROW, comme ici sur un Table Scan:<\/p>\n<p><a href=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/inrow_bitmap_filter.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4379\" title=\"inrow_bitmap_filter\" src=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/inrow_bitmap_filter.png\" alt=\"\" width=\"329\" height=\"141\" srcset=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/inrow_bitmap_filter.png 329w, https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/inrow_bitmap_filter-300x128.png 300w\" sizes=\"auto, (max-width: 329px) 100vw, 329px\" \/><\/a><\/p>\n<p>Il est possible d&#8217;observer cependant des \u00e9carts d&#8217;estimation car l&#8217;optimiseur ne sait pas \u00e0 l&#8217;avance combien de lignes seront \u00e9cart\u00e9es. Par exemple sur ce Table Scan de 5 millions de lignes, le Bitmap filtre 2488 lignes:<\/p>\n<p><a href=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/bitmapestimatesdifferences.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4380\" title=\"bitmapestimatesdifferences\" src=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/bitmapestimatesdifferences.png\" alt=\"\" width=\"540\" height=\"240\" srcset=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/bitmapestimatesdifferences.png 540w, https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/bitmapestimatesdifferences-300x133.png 300w\" sizes=\"auto, (max-width: 540px) 100vw, 540px\" \/><\/a><\/p>\n<p>Il ne faut pas se laisser tromper par les apparences. Il n&#8217;y a ici ni probl\u00e8mes de statistiques, ni de timeout dans la g\u00e9n\u00e9ration du plan, ni aucun autre facteur qui pourrait expliquer cette diff\u00e9rence. La diff\u00e9rence vient du Bitmap filter, et elle est parfaitement normale.<\/p>\n<p>A+. David B.<\/p>\n<p><em>\u00a0R\u00e9f\u00e9rences:<\/em><br \/>\n(1) <a href=\"https:\/\/blogs.msdn.com\/b\/craigfr\/archive\/2007\/04\/17\/parallel-query-execution-presentation.aspx\">Parallel Query Execution whitepaper- Craig Freedman (MSFT)<\/a><br \/>\n(2) <a href=\"https:\/\/blogs.msdn.com\/b\/psssql\/archive\/2008\/02\/13\/how-it-works-sql-server-per-query-degree-of-parallelism-worker-count-s.aspx\">How it Works: SQL Server Per Query Degree Of Parallelism Worker Count(s) Bob Dorr (MSFT &#8211; PSS) <\/a><br \/>\n(3) <a href=\"https:\/\/support.microsoft.com\/kb\/2806535\/en-us\">https:\/\/support.microsoft.com\/kb\/2806535\/en-us<\/a><br \/>\n(4) <a href=\"https:\/\/sqlblog.com\/blogs\/paul_white\/archive\/2011\/07\/07\/bitmap-magic.aspx\">Bitmap Magic (or\u2026 how SQL Server uses bitmap filters) Paul White (MVP) <\/a><\/p>\n<p>&nbsp;<\/p>\n<a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-twitter nolightbox\" data-provider=\"twitter\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Twitter\" href=\"https:\/\/twitter.com\/intent\/tweet?url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F3828&#038;text=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"twitter\" title=\"Share on Twitter\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/twitter.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-linkedin nolightbox\" data-provider=\"linkedin\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Linkedin\" href=\"https:\/\/www.linkedin.com\/shareArticle?mini=true&#038;url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F3828&#038;title=Parall%C3%A9lisme\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"linkedin\" title=\"Share on Linkedin\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/linkedin.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-mail nolightbox\" data-provider=\"mail\" rel=\"nofollow\" title=\"Share by email\" href=\"mailto:?subject=Parall%C3%A9lisme&#038;body=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20:%20https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F3828\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"mail\" title=\"Share by email\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/mail.png\" \/><\/a>","protected":false},"excerpt":{"rendered":"<p>Un post assez condens\u00e9 pour rappeler les \u00e9l\u00e9ments cl\u00e9s \u00e0 garder \u00e0 l&#8217;esprit lorsque l&#8217;on parle de parall\u00e9lisme sur SQL Server. Il suppose que vous soyez familiers du concept. Si ce n&#8217;est pas le cas, la visite commence par cet&hellip; <a href=\"https:\/\/blog.capdata.fr\/index.php\/parallelisme\/\" class=\"more-link\">Continuer la lecture <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":4378,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[227,232],"class_list":["post-3828","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-sqlserver","tag-maxdop","tag-parallelisme"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.8 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Parall\u00e9lisme - Capdata TECH BLOG<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.capdata.fr\/index.php\/parallelisme\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Parall\u00e9lisme - Capdata TECH BLOG\" \/>\n<meta property=\"og:description\" content=\"Un post assez condens\u00e9 pour rappeler les \u00e9l\u00e9ments cl\u00e9s \u00e0 garder \u00e0 l&#8217;esprit lorsque l&#8217;on parle de parall\u00e9lisme sur SQL Server. Il suppose que vous soyez familiers du concept. Si ce n&#8217;est pas le cas, la visite commence par cet&hellip; Continuer la lecture &rarr;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.capdata.fr\/index.php\/parallelisme\/\" \/>\n<meta property=\"og:site_name\" content=\"Capdata TECH BLOG\" \/>\n<meta property=\"article:published_time\" content=\"2013-05-30T13:59:08+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-11-21T16:02:28+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/Bitmapexample1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"662\" \/>\n\t<meta property=\"og:image:height\" content=\"166\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"David Baffaleuf\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u00c9crit par\" \/>\n\t<meta name=\"twitter:data1\" content=\"David Baffaleuf\" \/>\n\t<meta name=\"twitter:label2\" content=\"Dur\u00e9e de lecture estim\u00e9e\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/parallelisme\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/parallelisme\/\"},\"author\":{\"name\":\"David Baffaleuf\",\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/person\/136297da9f61d6e4878abe0f48bc5fbf\"},\"headline\":\"Parall\u00e9lisme\",\"datePublished\":\"2013-05-30T13:59:08+00:00\",\"dateModified\":\"2022-11-21T16:02:28+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/parallelisme\/\"},\"wordCount\":1859,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/blog.capdata.fr\/#organization\"},\"keywords\":[\"maxdop\",\"parallelisme\"],\"articleSection\":[\"SQL Server\"],\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/blog.capdata.fr\/index.php\/parallelisme\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/parallelisme\/\",\"url\":\"https:\/\/blog.capdata.fr\/index.php\/parallelisme\/\",\"name\":\"Parall\u00e9lisme - Capdata TECH BLOG\",\"isPartOf\":{\"@id\":\"https:\/\/blog.capdata.fr\/#website\"},\"datePublished\":\"2013-05-30T13:59:08+00:00\",\"dateModified\":\"2022-11-21T16:02:28+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/parallelisme\/#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.capdata.fr\/index.php\/parallelisme\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/parallelisme\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/blog.capdata.fr\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Parall\u00e9lisme\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.capdata.fr\/#website\",\"url\":\"https:\/\/blog.capdata.fr\/\",\"name\":\"Capdata TECH BLOG\",\"description\":\"Le blog technique sur les bases de donn\u00e9es de CAP DATA Consulting\",\"publisher\":{\"@id\":\"https:\/\/blog.capdata.fr\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.capdata.fr\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"fr-FR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/blog.capdata.fr\/#organization\",\"name\":\"Capdata TECH BLOG\",\"url\":\"https:\/\/blog.capdata.fr\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp\",\"contentUrl\":\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp\",\"width\":800,\"height\":254,\"caption\":\"Capdata TECH BLOG\"},\"image\":{\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.linkedin.com\/company\/cap-data-consulting\/mycompany\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/person\/136297da9f61d6e4878abe0f48bc5fbf\",\"name\":\"David Baffaleuf\",\"sameAs\":[\"http:\/\/www.capdata.fr\"],\"url\":\"https:\/\/blog.capdata.fr\/index.php\/author\/dbaffaleuf\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Parall\u00e9lisme - Capdata TECH BLOG","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.capdata.fr\/index.php\/parallelisme\/","og_locale":"fr_FR","og_type":"article","og_title":"Parall\u00e9lisme - Capdata TECH BLOG","og_description":"Un post assez condens\u00e9 pour rappeler les \u00e9l\u00e9ments cl\u00e9s \u00e0 garder \u00e0 l&#8217;esprit lorsque l&#8217;on parle de parall\u00e9lisme sur SQL Server. Il suppose que vous soyez familiers du concept. Si ce n&#8217;est pas le cas, la visite commence par cet&hellip; Continuer la lecture &rarr;","og_url":"https:\/\/blog.capdata.fr\/index.php\/parallelisme\/","og_site_name":"Capdata TECH BLOG","article_published_time":"2013-05-30T13:59:08+00:00","article_modified_time":"2022-11-21T16:02:28+00:00","og_image":[{"width":662,"height":166,"url":"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/05\/Bitmapexample1.png","type":"image\/png"}],"author":"David Baffaleuf","twitter_card":"summary_large_image","twitter_misc":{"\u00c9crit par":"David Baffaleuf","Dur\u00e9e de lecture estim\u00e9e":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blog.capdata.fr\/index.php\/parallelisme\/#article","isPartOf":{"@id":"https:\/\/blog.capdata.fr\/index.php\/parallelisme\/"},"author":{"name":"David Baffaleuf","@id":"https:\/\/blog.capdata.fr\/#\/schema\/person\/136297da9f61d6e4878abe0f48bc5fbf"},"headline":"Parall\u00e9lisme","datePublished":"2013-05-30T13:59:08+00:00","dateModified":"2022-11-21T16:02:28+00:00","mainEntityOfPage":{"@id":"https:\/\/blog.capdata.fr\/index.php\/parallelisme\/"},"wordCount":1859,"commentCount":0,"publisher":{"@id":"https:\/\/blog.capdata.fr\/#organization"},"keywords":["maxdop","parallelisme"],"articleSection":["SQL Server"],"inLanguage":"fr-FR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/blog.capdata.fr\/index.php\/parallelisme\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/blog.capdata.fr\/index.php\/parallelisme\/","url":"https:\/\/blog.capdata.fr\/index.php\/parallelisme\/","name":"Parall\u00e9lisme - Capdata TECH BLOG","isPartOf":{"@id":"https:\/\/blog.capdata.fr\/#website"},"datePublished":"2013-05-30T13:59:08+00:00","dateModified":"2022-11-21T16:02:28+00:00","breadcrumb":{"@id":"https:\/\/blog.capdata.fr\/index.php\/parallelisme\/#breadcrumb"},"inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.capdata.fr\/index.php\/parallelisme\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/blog.capdata.fr\/index.php\/parallelisme\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/blog.capdata.fr\/"},{"@type":"ListItem","position":2,"name":"Parall\u00e9lisme"}]},{"@type":"WebSite","@id":"https:\/\/blog.capdata.fr\/#website","url":"https:\/\/blog.capdata.fr\/","name":"Capdata TECH BLOG","description":"Le blog technique sur les bases de donn\u00e9es de CAP DATA Consulting","publisher":{"@id":"https:\/\/blog.capdata.fr\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.capdata.fr\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"fr-FR"},{"@type":"Organization","@id":"https:\/\/blog.capdata.fr\/#organization","name":"Capdata TECH BLOG","url":"https:\/\/blog.capdata.fr\/","logo":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/","url":"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp","contentUrl":"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp","width":800,"height":254,"caption":"Capdata TECH BLOG"},"image":{"@id":"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.linkedin.com\/company\/cap-data-consulting\/mycompany\/"]},{"@type":"Person","@id":"https:\/\/blog.capdata.fr\/#\/schema\/person\/136297da9f61d6e4878abe0f48bc5fbf","name":"David Baffaleuf","sameAs":["http:\/\/www.capdata.fr"],"url":"https:\/\/blog.capdata.fr\/index.php\/author\/dbaffaleuf\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts\/3828","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/comments?post=3828"}],"version-history":[{"count":115,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts\/3828\/revisions"}],"predecessor-version":[{"id":9524,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts\/3828\/revisions\/9524"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/media\/4378"}],"wp:attachment":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/media?parent=3828"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/categories?post=3828"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/tags?post=3828"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}