{"id":962,"date":"2016-09-05T22:01:33","date_gmt":"2016-09-05T22:01:33","guid":{"rendered":"http:\/\/nenadnoveljic.com\/blog\/?p=962"},"modified":"2016-09-05T22:01:33","modified_gmt":"2016-09-05T22:01:33","slug":"table-spool-performance-problem","status":"publish","type":"post","link":"https:\/\/nenadnoveljic.com\/blog\/table-spool-performance-problem\/","title":{"rendered":"Table Spool Performance Problem"},"content":{"rendered":"<h1>Introduction<\/h1>\n<p>While exploring <a href=\"http:\/\/nenadnoveljic.com\/blog\/nested-loop-join-heuristics\/\" target=\"_blank\">Nested Loop Join Heuristics<\/a>, I noticed that the SQL Server Query Opimizer had introduced a <a href=\"https:\/\/www.simple-talk.com\/sql\/learn-sql-server\/showplan-operator-of-the-week-lazy-spool\/\" target=\"_blank\">Lazy Table Spool<\/a> operator in\u00a0a Nested Loop Join (NLJ). In particular, the Lazy Table Spool appeared in the inner table of a simple NLJ which didn&#8217;t have any additional predicates. Furthermore, the number of logical reads exploded due to the Table Spool operator.<\/p>\n<h1>Setting the Scene<\/h1>\n<p>To demonstrate this anomaly, I&#8217;ll create two test tables, one large with a milion records and one small with just two records:<\/p>\n<pre><code>\r\nSELECT TOP (1000000)\r\nid = CONVERT(INT, ROW_NUMBER() OVER (ORDER BY s1.[object_id])),\r\na = CONVERT(INT, ROW_NUMBER() OVER (ORDER BY s1.[object_id]))\r\nINTO t_large\r\nFROM sys.all_objects AS s1 CROSS JOIN sys.all_objects AS s2\r\nOPTION (MAXDOP 1);\r\n\r\ncreate table t_small (b integer,c integer) ;\r\ninsert into t_mall values (1,1) ;\r\ninsert into t_mall values (2,2) ;\r\n<\/code><\/pre>\n<p>The <a href=\"http:\/\/sqlperformance.com\/2013\/01\/t-sql-queries\/generate-a-set-1\" target=\"_blank\">query to populate the large table with numbers<\/a> is used by courtesy of Aaron Bertrand.<\/p>\n<p>The execution plans will be analyzed for the following query which simply joins both of the tables:<\/p>\n<pre><code>select a from t_small s join t_large l on l.id = s.b option (recompile)<\/code><\/pre>\n<h1>Hash Join<\/h1>\n<p>As expected, the optimizer chose the Hash Join algorithm:<\/p>\n<pre><code>\r\nStmtText\tTotalSubtreeCost\r\nselect a from t_small s join t_large l on l.id = s.b option (recompile)\t10.49784\r\n  |--Hash Match(Inner Join, HASH:([s].[b])=([l].[id]), RESIDUAL:([master].[dbo].[t_small].[b] as [s].[b]=[master].[dbo].[t_large].[id] as [l].[id]))\t10.49784\r\n       |--Table Scan(OBJECT:([master].[dbo].[t_small] AS [s]))\t0.0032842\r\n       |--Table Scan(OBJECT:([master].[dbo].[t_large] AS [l]))\t3.94106\r\n<\/code><\/pre>\n<h1>Nested Loop Join With Table Spool<\/h1>\n<p>However, if we enforce a NLJ with the hint, Query Optimizer will introduce\u00a0the Lazy Table Spool of the inner table resulting in the total estimated cost 13.27454.<\/p>\n<pre><code>\r\nStmtText\t<span style=\"color: #ff0000;\">PhysicalOp<\/span>\tLogicalOp\tEstimateRows\tEstimateIO\tEstimateCPU\t<span style=\"color: #ff0000;\">TotalSubtreeCost<\/span>\tEstimateExecutions\r\nselect a from t_small s join t_large l on l.id = s.b option (<span style=\"color: #ff0000;\">loop join<\/span>, recompile)\tNULL\tNULL\t2.153138\tNULL\tNULL\t<span style=\"color: #ff0000;\">13.27454<\/span>\tNULL\r\n  |--<span style=\"color: #ff0000;\">Nested Loops<\/span>(Inner Join, WHERE:([master].[dbo].[t_small].[b] as [s].[b]=[master].[dbo].[t_large].[id] as [l].[id]))\tNested Loops\tInner Join\t2.153138\t0\t8.36\t13.27454\t1\r\n       |--Table Scan(OBJECT:([master].[dbo].[t_small] AS [s]))\tTable Scan\tTable Scan\t2\t0.003125\t0.0001592\t0.0032842\t1\r\n       |--<span style=\"color: #ff0000;\">Table Spool\tTable Spool<\/span>\tLazy Spool\t1000000\t0.01\t0.1801002\t<span style=\"color: #ff0000;\">4.31126<\/span>\t2\r\n            |--Table Scan(OBJECT:([master].[dbo].[t_large] AS [l]))\tTable Scan\tTable Scan\t1000000\t2.840903\t1.100157\t3.94106\t1<\/code><\/pre>\n<h1>Nested Loop Join Without Table Spool<\/h1>\n<p>Next, let&#8217;s check what will be the cost of the NLJ without the Table Spool:<\/p>\n<pre><code>\r\nStmtText\t<span style=\"color: #ff0000;\">PhysicalOp<\/span>\tLogicalOp\tEstimateRows\tEstimateIO\tEstimateCPU\t<span style=\"color: #ff0000;\">TotalSubtreeCost<\/span>\tEstimateExecutions\r\nselect a from t_small s join t_large l on l.id = s.b option (<span style=\"color: #ff0000;\">loop join<\/span>, recompile)\tNULL\tNULL\t2.153138\tNULL\tNULL\t<span style=\"color: #ff0000;\">14.00442<\/span>\tNULL\r\n  |--<span style=\"color: #ff0000;\">Nested Loops<\/span>(Inner Join, WHERE:([master].[dbo].[t_small].[b] as [s].[b]=[master].[dbo].[t_large].[id] as [l].[id]))\tNested Loops\tInner Join\t2.153138\t0\t8.36\t14.00442\t1\r\n       |--Table Scan(OBJECT:([master].[dbo].[t_small] AS [s]))\tTable Scan\tTable Scan\t2\t0.003125\t0.0001592\t0.0032842\t1\r\n       |--Table Scan(OBJECT:([master].[dbo].[t_large] AS [l]))\tTable Scan\tTable Scan\t1000000\t2.840981\t1.100078\t5.041138\t2\r\n<\/code><\/pre>\n<p>Note: the execution plan without the Table Spool was produced by switching off the\u00a0<em>BuildSPool<\/em> query transformation:<\/p>\n<pre><code>DBCC RULEOFF('BuildSpool')<\/code><\/pre>\n<p>Query optimizer\u00a0estimated cost 14.00442 for the plan without the Table Spool.<\/p>\n<h1>Scrutinizing Table Spool<\/h1>\n<p>In this case, there aren&#8217;t any filter predicates on <em>t_large<\/em>, so the whole table will be spooled into the <em>tempdb<\/em>. Thus, I can&#8217;t see any reason, why the calculated cost of the plan with the Table Spool should be lower than that of the plan without the Table Spool, 13.27454 and 14.00442, respectively? Not only does the spooling into the working table in the\u00a0<em>tempdb<\/em> introduce an IO overhead, but also why would the join with the working table in the tempdb be more efficient than the join with the regular table in a user database?<\/p>\n<p>However, spooling would generally make sense in the cases where there are filter predicates on the inner table, because the Nested Loop would be executed only on a\u00a0subset of data of the inner table\u00a0that is materialized in the <em>tempdb<\/em> as a result of the Table Spool operator.<\/p>\n<h1>Execution Statistics<\/h1>\n<p>Finally, I&#8217;ll\u00a0collect the IO and time statistics in order to measure by how\u00a0much the cost estimation of Table Spool deviates from reality:<\/p>\n<p>With Table Spool:<\/p>\n<pre><code>\r\nTable 't_large'. Scan count 1, logical reads <span style=\"color: #ff0000;\">3832<\/span>, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.\r\n\r\nTable 'Worktable'. Scan count 1, logical reads <span style=\"color: #ff0000;\">2864860<\/span>, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.\r\n\r\nTable 't_small'. Scan count 1, logical reads 1, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.\r\n\r\nSQL Server Execution Times:\r\n   CPU time = 3171 ms,  elapsed time = <span style=\"color: #ff0000;\">3233 ms<\/span>.\r\n<\/code><\/pre>\n<p>Without Table Spool:<\/p>\n<pre><code>\r\nTable 't_large'. Scan count 1, logical reads <span style=\"color: #ff0000;\">7664<\/span>, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.\r\n\r\nTable 't_small'. Scan count 1, logical reads 1, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.\r\n\r\nSQL Server Execution Times:\r\n   CPU time = 235 ms,  elapsed time = <span style=\"color: #ff0000;\">237 ms<\/span>.\r\n<\/code><\/pre>\n<p>Obviously, something got entirely wrong with the Table Spool. As expected, the inner table <em>t_large<\/em> was scanned only once for creating the <em>Worktable<\/em> (3832 logical reads). However, the NLJ to the inner <em>Worktable<\/em>\u00a0led to\u00a0the devastating 2864860 logical reads, which could not be explained at all!\u00a0As a consequence, the query execution time\u00a0skyrocketed\u00a0from\u00a0237 ms to 3233 ms.<\/p>\n<p>In contrast, the statistics for the plan without the Table Spool were as expected &#8211; the inner table <em>t_large <\/em>was scanned exactly 7664 times; once for each of the two records of the outer table <em>t_small<\/em>.<\/p>\n<h1>Eliminating Table Spool<\/h1>\n<p>Please note, that the test case above has been engineered in\u00a0a lab environment to show that there might be issues with the Table Spool. Hence, it might be worth paying closer attention when this operator appears in the execution plan. In this particular case, Table Spool can be completely eliminated by proper indexing:<\/p>\n<pre><code>CREATE NONCLUSTERED INDEX [idx_t_large_id]\r\nON [dbo].[t_large] ([id])\r\nINCLUDE ([a])\r\n\r\nStmtText\u00a0TotalSubtreeCost\r\nselect a from t_small s join t_large l on l.id = s.b\u00a00.00673376\r\n\u00a0 |--Nested Loops(Inner Join, OUTER REFERENCES:([s].[b]))\u00a00.00673376\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 |--Table Scan(OBJECT:([master].[dbo].[t_small] AS [s]))\u00a00.0032842\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 |--<span style=\"color: #ff0000;\">Index Seek<\/span>(OBJECT:([master].[dbo].[t_large].[idx_t_large_id] AS [l]), SEEK:([l].[id]=[master].[dbo].[t_small].[b] as [s].[b]) ORDERED FORWARD)\u00a00.0034412\r\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Table Spool can degrade SQL Server performance.  <a href=\"https:\/\/nenadnoveljic.com\/blog\/table-spool-performance-problem\/\" 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,17],"tags":[],"class_list":["post-962","post","type-post","status-publish","format-standard","hentry","category-cost-based-optimizer","category-sql-server"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Table Spool Performance Problem - All-round Database Topics<\/title>\n<meta name=\"description\" content=\"Table Spool can degrade SQL Server performance.\" \/>\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\/table-spool-performance-problem\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Table Spool Performance Problem - All-round Database Topics\" \/>\n<meta property=\"og:description\" content=\"Table Spool can degrade SQL Server performance.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/nenadnoveljic.com\/blog\/table-spool-performance-problem\/\" \/>\n<meta property=\"og:site_name\" content=\"All-round Database Topics\" \/>\n<meta property=\"article:published_time\" content=\"2016-09-05T22:01:33+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=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/table-spool-performance-problem\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/table-spool-performance-problem\\\/\"},\"author\":{\"name\":\"Nenad Noveljic\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/#\\\/schema\\\/person\\\/51458d9dd86dbbdd19f5add451d44efa\"},\"headline\":\"Table Spool Performance Problem\",\"datePublished\":\"2016-09-05T22:01:33+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/table-spool-performance-problem\\\/\"},\"wordCount\":554,\"commentCount\":0,\"articleSection\":[\"cost based optimizer\",\"SQL Server\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/table-spool-performance-problem\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/table-spool-performance-problem\\\/\",\"url\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/table-spool-performance-problem\\\/\",\"name\":\"Table Spool Performance Problem - All-round Database Topics\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/#website\"},\"datePublished\":\"2016-09-05T22:01:33+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/#\\\/schema\\\/person\\\/51458d9dd86dbbdd19f5add451d44efa\"},\"description\":\"Table Spool can degrade SQL Server performance.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/table-spool-performance-problem\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/table-spool-performance-problem\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/table-spool-performance-problem\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Table Spool Performance Problem\"}]},{\"@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":"Table Spool Performance Problem - All-round Database Topics","description":"Table Spool can degrade SQL Server performance.","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\/table-spool-performance-problem\/","og_locale":"en_US","og_type":"article","og_title":"Table Spool Performance Problem - All-round Database Topics","og_description":"Table Spool can degrade SQL Server performance.","og_url":"https:\/\/nenadnoveljic.com\/blog\/table-spool-performance-problem\/","og_site_name":"All-round Database Topics","article_published_time":"2016-09-05T22:01:33+00:00","author":"Nenad Noveljic","twitter_card":"summary_large_image","twitter_creator":"@NenadNoveljic","twitter_misc":{"Written by":"Nenad Noveljic","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/nenadnoveljic.com\/blog\/table-spool-performance-problem\/#article","isPartOf":{"@id":"https:\/\/nenadnoveljic.com\/blog\/table-spool-performance-problem\/"},"author":{"name":"Nenad Noveljic","@id":"https:\/\/nenadnoveljic.com\/blog\/#\/schema\/person\/51458d9dd86dbbdd19f5add451d44efa"},"headline":"Table Spool Performance Problem","datePublished":"2016-09-05T22:01:33+00:00","mainEntityOfPage":{"@id":"https:\/\/nenadnoveljic.com\/blog\/table-spool-performance-problem\/"},"wordCount":554,"commentCount":0,"articleSection":["cost based optimizer","SQL Server"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/nenadnoveljic.com\/blog\/table-spool-performance-problem\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/nenadnoveljic.com\/blog\/table-spool-performance-problem\/","url":"https:\/\/nenadnoveljic.com\/blog\/table-spool-performance-problem\/","name":"Table Spool Performance Problem - All-round Database Topics","isPartOf":{"@id":"https:\/\/nenadnoveljic.com\/blog\/#website"},"datePublished":"2016-09-05T22:01:33+00:00","author":{"@id":"https:\/\/nenadnoveljic.com\/blog\/#\/schema\/person\/51458d9dd86dbbdd19f5add451d44efa"},"description":"Table Spool can degrade SQL Server performance.","breadcrumb":{"@id":"https:\/\/nenadnoveljic.com\/blog\/table-spool-performance-problem\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/nenadnoveljic.com\/blog\/table-spool-performance-problem\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/nenadnoveljic.com\/blog\/table-spool-performance-problem\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/nenadnoveljic.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Table Spool Performance Problem"}]},{"@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\/962","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=962"}],"version-history":[{"count":1,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/posts\/962\/revisions"}],"predecessor-version":[{"id":997,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/posts\/962\/revisions\/997"}],"wp:attachment":[{"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/media?parent=962"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/categories?post=962"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/tags?post=962"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}