{"id":2654,"date":"2019-07-10T16:41:47","date_gmt":"2019-07-10T16:41:47","guid":{"rendered":"https:\/\/nenadnoveljic.com\/blog\/?p=2654"},"modified":"2019-07-10T16:41:50","modified_gmt":"2019-07-10T16:41:50","slug":"extracting-join-order-optimizer-trace","status":"publish","type":"post","link":"https:\/\/nenadnoveljic.com\/blog\/extracting-join-order-optimizer-trace\/","title":{"rendered":"Extracting Join Order from Optimizer Trace"},"content":{"rendered":"<p>In <a href=\"https:\/\/nenadnoveljic.com\/blog\/extracting-query-block-optimizer-trace\/\">my previous blog post<\/a>, I introduced <a href=\"https:\/\/github.com\/nenadnoveljic\/blogs\/blob\/master\/extracting_query_block_optimizer_trace\/opt_qb.awk\">opt_qb.awk<\/a>, a script for extracting the most relevant information for a given query block (QB) from optimizer trace:<\/p>\n<pre><code><a href=\"https:\/\/github.com\/nenadnoveljic\/blogs\/blob\/master\/extracting_query_block_optimizer_trace\/opt_qb.awk\">opt_qb.awk<\/a> -v qb=QB_MAIN optimizer_trace_file\n---------------\n24 Registered qb: QB_MAIN 0xc78a0038 (HINT QB_MAIN)\n200183 Final cost for query block QB_MAIN (#1) - All Rows Plan:\n200184   <span style=\"color:red\">Best join order: 55<\/span>\n200185   Cost: 9827.131413  Degree: 1  Card: 126870.000000  Bytes: 273404850.000000<\/code><\/pre>\n<p>The output above contains, among others, the best join order number, though, no any further details about it. The calculations for different join orders were done much before, and as its name implies, the join order section contains the order in which the tables are joined, but also the intermediate cost calculation results for different join types. It&#8217;s undoubtedly very important information for understanding the optimizer decisions, but as the whole section commonly consists of thousands of lines, which, in addition, are placed much before the QB summary, it might take some time to find and extract the information of interest.<\/p>\n<p>For this reason, I wrote <a href=\"https:\/\/github.com\/nenadnoveljic\/blogs\/blob\/master\/extracting_join_order_optimizer_trace\/opt_jo.awk\">opt_jo.awk<\/a>, a script for displaying the cost calculation results summary for a given join order.<\/p>\n<p>Let&#8217;s use it now for drilling down. <a href=\"https:\/\/github.com\/nenadnoveljic\/blogs\/blob\/master\/extracting_query_block_optimizer_trace\/opt_qb.awk\">opt_qb.awk<\/a> showed that the optimal join order is <span style=\"color:red\">55<\/span>, so I&#8217;m going to specify it as the input parameter to <a href=\"https:\/\/github.com\/nenadnoveljic\/blogs\/blob\/master\/extracting_join_order_optimizer_trace\/opt_jo.awk\">opt_jo.awk<\/a>:<\/p>\n<pre><code><a href=\"https:\/\/github.com\/nenadnoveljic\/blogs\/blob\/master\/extracting_join_order_optimizer_trace\/opt_jo.awk\">opt_jo.awk<\/a> -v qb=QB_MAIN -v <span style=\"color:red\">jo=55<\/span> optimizer_trace_file\n\n#################\n23924 Query Block QB_MAIN (#1)\n=================\n37199 <span style=\"color:red\">Join order[55]<\/span>:  <span style=\"color:blue\">TAB_1#1  TAB_2#9  TAB_3#8  TAB_4#5  TAB_5#4<\/span>  <span style=\"color:brown\">TAB_6#7<\/span>  TAB_7#0  TAB_8#2  TAB_9#3  TAB_10#6\n-----------------\n37202 Now joining: <span style=\"color:brown\">TAB_6#7<\/span>\n37274   Best NL cost: 132871.483354\n37302   SM cost: 63265.650482 \n37322   HA cost: 8622.012333 swapped \n37325 Best:: JoinMethod: Hash\n37326        Cost: 8622.012333  Degree: 1  Resp: 8622.012333  Card: 126869.775717 Bytes: \n-----------------\n37329 Now joining: TAB_7#0\n37340   Best NL cost: 79989834.996156\n37368   SM cost: 64302.055187 \n37388   HA cost: 9252.984437 swapped \n37391 Best:: JoinMethod: Hash\n37392        Cost: 9252.984437  Degree: 1  Resp: 9252.984437  Card: 126869.775717 Bytes: \n-----------------\n37395 Now joining: TAB_8#2\n37438   Best NL cost: 10001.244263\n37466   SM cost: 64475.729580 \n37486   HA cost: 9259.545341 swapped \n37489 Best:: JoinMethod: Hash\n37490        Cost: 9259.545341  Degree: 1  Resp: 9259.545341  Card: 126869.775717 Bytes: \n-----------------\n37493 Now joining: TAB_9#3\n37504   Best NL cost: 48435094.585054\n37532   SM cost: 66031.786006 \n37552   HA cost: 9641.804044 swapped \n37555 Best:: JoinMethod: Hash\n37556        Cost: 9641.804044  Degree: 1  Resp: 9641.804044  Card: 126869.775717 Bytes: \n-----------------\n37559 Now joining: TAB_10#6\n37636   Best NL cost: 136560.628579\n37664   SM cost: 66305.446946 \n37684   HA cost: 9746.850757 swapped \n37687 Best:: JoinMethod: HashSemi\n37688        Cost: 9746.850757  Degree: 1  Resp: 9746.850757  Card: 126869.775717 Bytes: <\/code><\/pre>\n<p>By looking at the output above, we can easily compare the cost of each join type and see why, for example, NL was discarded.<\/p>\n<p>At this point, you might wonder where the calculation for the first five tables is and why the optimizer started the calculation for <span style=\"color:brown\">TAB_6<\/span>, which is only the 6th table in the join order.<\/p>\n<p>That&#8217;s a consequence of the optimization employed in the cost calculation. The calculation for the first five tables had already been done in the join order 39, so the optimizer stored its value for the future calculations.<\/p>\n<pre><code><a href=\"https:\/\/github.com\/nenadnoveljic\/blogs\/blob\/master\/extracting_join_order_optimizer_trace\/opt_jo.awk\">opt_jo.awk<\/a> -v qb=QB_MAIN -v jo=39 optimizer_trace_file\n \n#################\n23924 Query Block QB_MAIN (#1)\n=================\n32775 Join order[39]:  <span style=\"color:blue\">TAB_1#1  TAB_2#9  TAB_3#8  TAB_4#5  TAB_5#4<\/span>  TAB_7#0  TAB_10#6  TAB_6#7  TAB_8#2  TAB_9#3\n-----------------\n32778 Now joining: <span style=\"color:blue\">TAB_5#4<\/span>\n32789   Best NL cost: 382588534.321321\n32817   SM cost: 12235.764853 \n32829   HA cost: 5880.070943  \n32832 Best:: JoinMethod: Hash\n32833        Cost: 5880.070943  Degree: 1  Resp: 5880.070943  Card: 126917.972455 Bytes: \n-----------------\n32836 Now joining: TAB_7#0\n32847   Best NL cost: 80017353.149534\n32875   SM cost: 60860.650906 \n32895   HA cost: 6511.043248 swapped \n32898 Best:: JoinMethod: Hash\n32899        Cost: 6511.043248  Degree: 1  Resp: 6511.043248  Card: 126917.972455 Bytes: \n-----------------\n32902 Now joining: TAB_10#6\n32979   Best NL cost: 133477.886254\n33007   SM cost: 61109.315695 \n33027   HA cost: 6616.090160 swapped \n33030 Best:: JoinMethod: HashSemi\n33031        Cost: 6616.090160  Degree: 1  Resp: 6616.090160  Card: 126917.972455 Bytes: \n-----------------\n33034 Now joining: TAB_6#7\n33106   Best NL cost: 133607.502571\n33134   SM cost: 64650.100407 \n33154   HA cost: 9358.031550 swapped \n33157 Best:: JoinMethod: Hash\n33158        Cost: 9358.031550  Degree: 1  Resp: 9358.031550  Card: 126869.775717 Bytes: \n-----------------\n33161 Now joining: TAB_8#2\n33204   Best NL cost: 10106.291375\n33232   SM cost: 65085.111004 \n33252   HA cost: 9364.592454 swapped \n33255 Best:: JoinMethod: Hash\n33256        Cost: 9364.592454  Degree: 1  Resp: 9364.592454  Card: 126869.775717 Bytes: \n-----------------\n33259 Now joining: TAB_9#3\n33270   Best NL cost: 48435199.632166\n33298   SM cost: 66641.167430 \n33318   HA cost: 9746.851157 swapped \n33321 Best:: JoinMethod: Hash\n33322        Cost: 9746.851157  Degree: 1  Resp: 9746.851157  Card: 126869.775717 Bytes: <\/code><\/pre>\n<p>I usually use opt_jo.awk as I did in the example above. I mean I first get the optimal join order number for the QB in question and then use opt_jo.awk for extracting more detailed information for the best join order. But you can also invoke it without any parameters to get the details for every tried permutation and the QB:<\/p>\n<pre><code>opt_jo [-v qb='QB_NAME'] [-v jo=join_order] optimizer_trace_file<\/code><\/pre>\n<p>As you have seen, it also prints the line numbers, so you can quickly position yourself within the trace file when looking for more information.<\/p>\n<p>By the way, I also published some other articles about programmatically parsing optimizer trace files:<\/p>\n<ul>\n<li><a href=\"https:\/\/nenadnoveljic.com\/blog\/extracting-query-block-optimizer-trace\/\">Extracting Query Block Information from Optimizer Trace<\/a><\/li>\n<li><a href=\"https:\/\/nenadnoveljic.com\/blog\/join-permutations-heatmaps\/\">Join Permutations Heatmaps<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Programmatically extracting join order information from optimizer trace <a href=\"https:\/\/nenadnoveljic.com\/blog\/extracting-join-order-optimizer-trace\/\" class=\"more-link\">Continue Reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[11,5],"tags":[],"class_list":["post-2654","post","type-post","status-publish","format-standard","hentry","category-cost-based-optimizer","category-oracle"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Extracting Join Order from Optimizer Trace - All-round Database Topics<\/title>\n<meta name=\"description\" content=\"Programmatically extracting join order information from optimizer trace\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/nenadnoveljic.com\/blog\/extracting-join-order-optimizer-trace\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Extracting Join Order from Optimizer Trace - All-round Database Topics\" \/>\n<meta property=\"og:description\" content=\"Programmatically extracting join order information from optimizer trace\" \/>\n<meta property=\"og:url\" content=\"https:\/\/nenadnoveljic.com\/blog\/extracting-join-order-optimizer-trace\/\" \/>\n<meta property=\"og:site_name\" content=\"All-round Database Topics\" \/>\n<meta property=\"article:published_time\" content=\"2019-07-10T16:41:47+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-07-10T16:41:50+00:00\" \/>\n<meta name=\"author\" content=\"Nenad Noveljic\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@NenadNoveljic\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Nenad Noveljic\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/extracting-join-order-optimizer-trace\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/extracting-join-order-optimizer-trace\\\/\"},\"author\":{\"name\":\"Nenad Noveljic\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/#\\\/schema\\\/person\\\/51458d9dd86dbbdd19f5add451d44efa\"},\"headline\":\"Extracting Join Order from Optimizer Trace\",\"datePublished\":\"2019-07-10T16:41:47+00:00\",\"dateModified\":\"2019-07-10T16:41:50+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/extracting-join-order-optimizer-trace\\\/\"},\"wordCount\":399,\"commentCount\":0,\"articleSection\":[\"cost based optimizer\",\"Oracle\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/extracting-join-order-optimizer-trace\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/extracting-join-order-optimizer-trace\\\/\",\"url\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/extracting-join-order-optimizer-trace\\\/\",\"name\":\"Extracting Join Order from Optimizer Trace - All-round Database Topics\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/#website\"},\"datePublished\":\"2019-07-10T16:41:47+00:00\",\"dateModified\":\"2019-07-10T16:41:50+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/#\\\/schema\\\/person\\\/51458d9dd86dbbdd19f5add451d44efa\"},\"description\":\"Programmatically extracting join order information from optimizer trace\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/extracting-join-order-optimizer-trace\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/extracting-join-order-optimizer-trace\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/extracting-join-order-optimizer-trace\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Extracting Join Order from Optimizer Trace\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/\",\"name\":\"All-round Database Topics\",\"description\":\"Nenad Noveljic\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/#\\\/schema\\\/person\\\/51458d9dd86dbbdd19f5add451d44efa\",\"name\":\"Nenad Noveljic\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a97b796613ea48ec8a7b79c8ffe1c685dcffc920c68121f6238d5caab5070670?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a97b796613ea48ec8a7b79c8ffe1c685dcffc920c68121f6238d5caab5070670?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a97b796613ea48ec8a7b79c8ffe1c685dcffc920c68121f6238d5caab5070670?s=96&d=mm&r=g\",\"caption\":\"Nenad Noveljic\"},\"sameAs\":[\"nenad-noveljic-9b746a6\",\"https:\\\/\\\/x.com\\\/NenadNoveljic\"],\"url\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/author\\\/nenad\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Extracting Join Order from Optimizer Trace - All-round Database Topics","description":"Programmatically extracting join order information from optimizer trace","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:\/\/nenadnoveljic.com\/blog\/extracting-join-order-optimizer-trace\/","og_locale":"en_US","og_type":"article","og_title":"Extracting Join Order from Optimizer Trace - All-round Database Topics","og_description":"Programmatically extracting join order information from optimizer trace","og_url":"https:\/\/nenadnoveljic.com\/blog\/extracting-join-order-optimizer-trace\/","og_site_name":"All-round Database Topics","article_published_time":"2019-07-10T16:41:47+00:00","article_modified_time":"2019-07-10T16:41:50+00:00","author":"Nenad Noveljic","twitter_card":"summary_large_image","twitter_creator":"@NenadNoveljic","twitter_misc":{"Written by":"Nenad Noveljic","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/nenadnoveljic.com\/blog\/extracting-join-order-optimizer-trace\/#article","isPartOf":{"@id":"https:\/\/nenadnoveljic.com\/blog\/extracting-join-order-optimizer-trace\/"},"author":{"name":"Nenad Noveljic","@id":"https:\/\/nenadnoveljic.com\/blog\/#\/schema\/person\/51458d9dd86dbbdd19f5add451d44efa"},"headline":"Extracting Join Order from Optimizer Trace","datePublished":"2019-07-10T16:41:47+00:00","dateModified":"2019-07-10T16:41:50+00:00","mainEntityOfPage":{"@id":"https:\/\/nenadnoveljic.com\/blog\/extracting-join-order-optimizer-trace\/"},"wordCount":399,"commentCount":0,"articleSection":["cost based optimizer","Oracle"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/nenadnoveljic.com\/blog\/extracting-join-order-optimizer-trace\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/nenadnoveljic.com\/blog\/extracting-join-order-optimizer-trace\/","url":"https:\/\/nenadnoveljic.com\/blog\/extracting-join-order-optimizer-trace\/","name":"Extracting Join Order from Optimizer Trace - All-round Database Topics","isPartOf":{"@id":"https:\/\/nenadnoveljic.com\/blog\/#website"},"datePublished":"2019-07-10T16:41:47+00:00","dateModified":"2019-07-10T16:41:50+00:00","author":{"@id":"https:\/\/nenadnoveljic.com\/blog\/#\/schema\/person\/51458d9dd86dbbdd19f5add451d44efa"},"description":"Programmatically extracting join order information from optimizer trace","breadcrumb":{"@id":"https:\/\/nenadnoveljic.com\/blog\/extracting-join-order-optimizer-trace\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/nenadnoveljic.com\/blog\/extracting-join-order-optimizer-trace\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/nenadnoveljic.com\/blog\/extracting-join-order-optimizer-trace\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/nenadnoveljic.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Extracting Join Order from Optimizer Trace"}]},{"@type":"WebSite","@id":"https:\/\/nenadnoveljic.com\/blog\/#website","url":"https:\/\/nenadnoveljic.com\/blog\/","name":"All-round Database Topics","description":"Nenad Noveljic","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/nenadnoveljic.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/nenadnoveljic.com\/blog\/#\/schema\/person\/51458d9dd86dbbdd19f5add451d44efa","name":"Nenad Noveljic","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/a97b796613ea48ec8a7b79c8ffe1c685dcffc920c68121f6238d5caab5070670?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/a97b796613ea48ec8a7b79c8ffe1c685dcffc920c68121f6238d5caab5070670?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a97b796613ea48ec8a7b79c8ffe1c685dcffc920c68121f6238d5caab5070670?s=96&d=mm&r=g","caption":"Nenad Noveljic"},"sameAs":["nenad-noveljic-9b746a6","https:\/\/x.com\/NenadNoveljic"],"url":"https:\/\/nenadnoveljic.com\/blog\/author\/nenad\/"}]}},"_links":{"self":[{"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/posts\/2654","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/comments?post=2654"}],"version-history":[{"count":1,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/posts\/2654\/revisions"}],"predecessor-version":[{"id":2666,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/posts\/2654\/revisions\/2666"}],"wp:attachment":[{"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/media?parent=2654"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/categories?post=2654"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/tags?post=2654"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}