{"id":48,"date":"2015-10-14T19:53:27","date_gmt":"2015-10-14T19:53:27","guid":{"rendered":"http:\/\/nenadnoveljic.com\/blog\/?p=48"},"modified":"2015-11-18T21:52:42","modified_gmt":"2015-11-18T21:52:42","slug":"sql-plan-directives-partitioned-tables","status":"publish","type":"post","link":"https:\/\/nenadnoveljic.com\/blog\/sql-plan-directives-partitioned-tables\/","title":{"rendered":"SQL plan directives on partitioned tables"},"content":{"rendered":"<h4>Introduction<\/h4>\n<p>The purpose of this post is to warn of an edge case where the cardinality estimate might significantly increase after adding a conjunctive filter predicate. This problem might arise in Oracle 12c due to sql plan directives on partitioned tables when there is a value which is rare in one partition, but appears frequently in other partitions.<\/p>\n<h4>Test data<\/h4>\n<p>Create the table with two partitions:<\/p>\n<pre><code>CREATE TABLE T\r\n(\r\nid number,\r\nvalue varchar2(10)\r\n)\r\nPARTITION BY RANGE (id)\r\n(\r\nPARTITION t_id_1 VALUES LESS THAN (2) ,\r\nPARTITION t_id_2 VALUES LESS THAN (3)\r\n);<\/code><\/pre>\n<p>Firstly, fill the second partition with both rare and popular data:<\/p>\n<pre><code>INSERT INTO T\r\nSELECT 2,'RARE_IN_2' value\r\nFROM dual\r\nCONNECT BY level &lt;= 1;\r\nINSERT INTO T\r\nSELECT 2,'POPULAR' value\r\nFROM dual\r\nCONNECT BY level &lt;= 1000000 ;<\/code><\/pre>\n<p>Secondly, insert the\u00a0rare values\u00a0from the second partition\u00a0into the first partition:<\/p>\n<pre>INSERT INTO T\r\nSELECT 1,'RARE_IN_2' value\r\nFROM dual\r\nCONNECT BY level &lt;= 1000;<\/pre>\n<p>Finally,\u00a0gather statistics:<\/p>\n<pre><code>EXEC DBMS_STATS.gather_table_stats('SYS', 'T');<\/code><\/pre>\n<h4>SQL plan directives<\/h4>\n<p>The following query selects the rare values from the second partition:<\/p>\n<pre><code>SELECT \/*+ GATHER_PLAN_STATISTICS *\/ *\r\nFROM t\r\nWHERE id = 2 and value = 'RARE_IN_2' ;<\/code><\/pre>\n<p>As expected, the estimated cardinality is wrong. As there are only two values in the table and the histograms are missing the optimizer thinks it would get the half\u00a0of the records back (500K):<\/p>\n<pre><code>-----------------------------------------------------------------------------------------\r\n| Id  | Operation              | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers \r\n-----------------------------------------------------------------------------------------\r\n|   0 | SELECT STATEMENT       |      |      1 |        |      1 |00:00:00.02 |    2211 \r\n|   1 |  PARTITION RANGE SINGLE|      |      1 |    500K|      1 |00:00:00.02 |    2211 \r\n|*  2 |   TABLE ACCESS FULL    | T    |      1 |    <span style=\"color: #ff0000;\">500K<\/span>|      <span style=\"color: #ff0000;\">1<\/span> |00:00:00.02 |    2211 \r\n-----------------------------------------------------------------------------------------       \r\nPredicate Information (identified by operation id):\r\n---------------------------------------------------\r\n  2 - filter((\"VALUE\"='RARE_IN_2' AND \"ID\"=2))<\/code><\/pre>\n<p>However, because of the \u201cAND\u201d clause in the filter predicate, the statistics feedback kicked in and as a result, the SQL plan directive was created:<\/p>\n<pre><code>EXEC DBMS_SPD.flush_sql_plan_directive;\r\n\r\nselect type,state,reason,notes\r\n  from dba_sql_plan_directives\r\n  where directive_id in(\r\n    select directive_id from dba_sql_plan_dir_objects\r\n      where owner='SYS' and object_name='T'\r\n);\r\n\r\nTYPE                 STATE  REASON                                                         \r\n-------------------- ------ ------------------------------------------------------------\r\nNOTES       \r\n----------------------------------------------------------------------------------------\r\nDYNAMIC_SAMPLING     USABLE SINGLE TABLE CARDINALITY MISESTIMATE\r\n&lt;spd_note&gt;\r\n  &lt;internal_state&gt;NEW&lt;\/internal_state&gt;\r\n  &lt;redundant&gt;NO&lt;\/redundant&gt;\r\n  &lt;spd_text&gt;{EC(SYS.T)[ID, VALUE]}&lt;\/spd_text&gt;\r\n&lt;\/spd_note&gt;<\/code><\/pre>\n<p>Thanks to dynamic sampling the cardinality estimate for the second execution is correct:<\/p>\n<pre><code>SELECT \/*+ GATHER_PLAN_STATISTICS *\/ *   \r\n  FROM   t t2   WHERE  id = 2\r\nand value = 'RARE_IN_2' ;\r\n-----------------------------------------------------------------------------------------\r\n| Id  | Operation              | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |\r\n-----------------------------------------------------------------------------------------\r\n|   0 | SELECT STATEMENT       |      |      1 |        |      1 |00:00:00.02 |    2211 |\r\n|   1 |  PARTITION RANGE SINGLE|      |      1 |      1 |      1 |00:00:00.02 |    2211 |\r\n|*  2 |   TABLE ACCESS FULL    | T    |      <span style=\"color: #ff0000;\">1<\/span> |      <span style=\"color: #ff0000;\">1<\/span> |      1 |00:00:00.02 |    2211 |\r\n-----------------------------------------------------------------------------------------\r\nPredicate Information (identified by operation id):\r\n---------------------------------------------------                                         \r\n   2 - filter((\"VALUE\"='RARE_IN_2' AND \"ID\"=2))\r\nNote\r\n-----                                            \r\n<span style=\"color: #ff0000;\">   - dynamic statistics used: dynamic sampling (level=2)\r\n   - 1 Sql Plan Directive used for this statement<\/span><\/code><\/pre>\n<p>Now, we are selecting all the data from the first partition. No surprise there, the estimate is correct:<\/p>\n<pre><code>SELECT \/*+ GATHER_PLAN_STATISTICS *\/ *   \r\n  FROM t WHERE  id = 1\r\n-----------------------------------------------------------------------------------------     \r\n| Id  | Operation              | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers \r\n-----------------------------------------------------------------------------------------\r\n|   0 | SELECT STATEMENT       |      |      1 |        |   1000 |00:00:00.01 |      72 \r\n|   1 |  PARTITION RANGE SINGLE|      |      1 |   1000 |   1000 |00:00:00.01 |      72 \r\n|*  2 |   TABLE ACCESS FULL    | T    |      1 |   <span style=\"color: #ff0000;\">1000<\/span> |   <span style=\"color: #ff0000;\">1000<\/span> |00:00:00.01 |      72 \r\n-----------------------------------------------------------------------------------------\r\nPredicate Information (identified by operation id):\r\n---------------------------------------------------\r\n   2 - filter(\"ID\"=1)<\/code><\/pre>\n<p>To stir up we will add a conjunctive predicate:<\/p>\n<pre><code>SELECT \/*+ GATHER_PLAN_STATISTICS *\/ *\r\n  FROM t WHERE  id = 1 <span style=\"color: #ff0000;\">and value = 'RARE_IN_2'<\/span> ;\r\n-----------------------------------------------------------------------------------------\r\n| Id  | Operation              | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers        \r\n-----------------------------------------------------------------------------------------\r\n|   0 | SELECT STATEMENT       |      |      1 |        |   1000 |00:00:00.01 |      72 \r\n|   1 |  PARTITION RANGE SINGLE|      |      1 |   2760 |   1000 |00:00:00.01 |      72 \r\n|*  2 |   TABLE ACCESS FULL    | T    |      1 |   <span style=\"color: #ff0000;\">2760<\/span> |   <span style=\"color: #ff0000;\">1000<\/span> |00:00:00.01 |      72 \r\n-----------------------------------------------------------------------------------------       \r\nPredicate Information (identified by operation id):\r\n---------------------------------------------------\r\n   2 - filter((\"ID\"=1 AND \"VALUE\"='RARE_IN_2'))                                               \r\nNote                                                                      \r\n-----                                           \r\n   <span style=\"color: #ff0000;\">- dynamic statistics used: dynamic sampling (level=2)\r\n   - 1 Sql Plan Directive used for this statement<\/span><\/code><\/pre>\n<p>The cardinality estimate soared which is counterintuitive\u00a0because\u00a0an additional &#8220;AND&#8221;\u00a0filter predicate can only\u00a0reduce the number of the returned rows.\u00a0What happened here? Because of the additional filter predicate the sql plan directive and dynamic sampling kicked in and produced the wrong estimate because of the skewed data. In this case, the basic column statistics would have\u00a0led to\u00a0a far better outcome:<\/p>\n<pre><code>SELECT \/*+ GATHER_PLAN_STATISTICS <span style=\"color: #ff0000;\">dynamic_sampling(0)<\/span> *\/ *\r\n  FROM   t WHERE  id = 1 and value = 'RARE_IN_2' ;\r\n-----------------------------------------------------------------------------------------\r\n| Id  | Operation              | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers \r\n-----------------------------------------------------------------------------------------\r\n|   0 | SELECT STATEMENT       |      |      1 |        |   1000 |00:00:00.01 |      72\r\n|   1 |  PARTITION RANGE SINGLE|      |      1 |   1000 |   1000 |00:00:00.01 |      72\r\n|*  2 |   TABLE ACCESS FULL    | T    |      1 |   <span style=\"color: #ff0000;\">1000<\/span> |   <span style=\"color: #ff0000;\">1000<\/span> |00:00:00.01 |      72\r\n-----------------------------------------------------------------------------------------\r\nPredicate Information (identified by operation id):\r\n---------------------------------------------------\r\n   2 - filter((\"ID\"=1 AND \"VALUE\"='RARE_IN_2'))\r\n<\/code><\/pre>\n<p>As a workaround, you might permanently disable the misleading\u00a0sql plan directive\u00a0by\u00a0using the procedure\u00a0described in the <a href=\"http:\/\/blog.dbi-services.com\/how-to-disable-a-sql-plan-directive-permanently\/\" target=\"_blank\">post<\/a>\u00a0by Franck Pachot and create the histogram on the skewed column.<\/p>\n<p>Update 18.11.2015: The Oracle Support filed a bug for the problem &#8211; Bug 22229118 : WRONG CARDINALITY ESTIMATE WITH SQL PLAN DIRECTIVE .<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The purpose of this post is to warn of an edge case where the cardinality estimate might significantly increase after adding a conjunctive filter predicate. This problem might arise in Oracle 12c due to sql plan directives on partitioned tables when there is a value which is rare in one partition, but appears frequently in other partitions. <a href=\"https:\/\/nenadnoveljic.com\/blog\/sql-plan-directives-partitioned-tables\/\" 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":[8,10,11,5],"tags":[],"class_list":["post-48","post","type-post","status-publish","format-standard","hentry","category-12c","category-adaptive-query-optimization","category-cost-based-optimizer","category-oracle"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>SQL plan directives on partitioned tables<\/title>\n<meta name=\"description\" content=\"SQL plan directives on partitioned tables with skewed data might cause worse cardinality estimates.\" \/>\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\/sql-plan-directives-partitioned-tables\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"SQL plan directives on partitioned tables\" \/>\n<meta property=\"og:description\" content=\"SQL plan directives on partitioned tables with skewed data might cause worse cardinality estimates.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/nenadnoveljic.com\/blog\/sql-plan-directives-partitioned-tables\/\" \/>\n<meta property=\"og:site_name\" content=\"All-round Database Topics\" \/>\n<meta property=\"article:published_time\" content=\"2015-10-14T19:53:27+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2015-11-18T21:52:42+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\\\/sql-plan-directives-partitioned-tables\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/sql-plan-directives-partitioned-tables\\\/\"},\"author\":{\"name\":\"Nenad Noveljic\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/#\\\/schema\\\/person\\\/51458d9dd86dbbdd19f5add451d44efa\"},\"headline\":\"SQL plan directives on partitioned tables\",\"datePublished\":\"2015-10-14T19:53:27+00:00\",\"dateModified\":\"2015-11-18T21:52:42+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/sql-plan-directives-partitioned-tables\\\/\"},\"wordCount\":327,\"commentCount\":3,\"articleSection\":[\"12c\",\"adaptive query optimization\",\"cost based optimizer\",\"Oracle\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/sql-plan-directives-partitioned-tables\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/sql-plan-directives-partitioned-tables\\\/\",\"url\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/sql-plan-directives-partitioned-tables\\\/\",\"name\":\"SQL plan directives on partitioned tables\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/#website\"},\"datePublished\":\"2015-10-14T19:53:27+00:00\",\"dateModified\":\"2015-11-18T21:52:42+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/#\\\/schema\\\/person\\\/51458d9dd86dbbdd19f5add451d44efa\"},\"description\":\"SQL plan directives on partitioned tables with skewed data might cause worse cardinality estimates.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/sql-plan-directives-partitioned-tables\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/sql-plan-directives-partitioned-tables\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/sql-plan-directives-partitioned-tables\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"SQL plan directives on partitioned tables\"}]},{\"@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":"SQL plan directives on partitioned tables","description":"SQL plan directives on partitioned tables with skewed data might cause worse cardinality estimates.","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\/sql-plan-directives-partitioned-tables\/","og_locale":"en_US","og_type":"article","og_title":"SQL plan directives on partitioned tables","og_description":"SQL plan directives on partitioned tables with skewed data might cause worse cardinality estimates.","og_url":"https:\/\/nenadnoveljic.com\/blog\/sql-plan-directives-partitioned-tables\/","og_site_name":"All-round Database Topics","article_published_time":"2015-10-14T19:53:27+00:00","article_modified_time":"2015-11-18T21:52:42+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\/sql-plan-directives-partitioned-tables\/#article","isPartOf":{"@id":"https:\/\/nenadnoveljic.com\/blog\/sql-plan-directives-partitioned-tables\/"},"author":{"name":"Nenad Noveljic","@id":"https:\/\/nenadnoveljic.com\/blog\/#\/schema\/person\/51458d9dd86dbbdd19f5add451d44efa"},"headline":"SQL plan directives on partitioned tables","datePublished":"2015-10-14T19:53:27+00:00","dateModified":"2015-11-18T21:52:42+00:00","mainEntityOfPage":{"@id":"https:\/\/nenadnoveljic.com\/blog\/sql-plan-directives-partitioned-tables\/"},"wordCount":327,"commentCount":3,"articleSection":["12c","adaptive query optimization","cost based optimizer","Oracle"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/nenadnoveljic.com\/blog\/sql-plan-directives-partitioned-tables\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/nenadnoveljic.com\/blog\/sql-plan-directives-partitioned-tables\/","url":"https:\/\/nenadnoveljic.com\/blog\/sql-plan-directives-partitioned-tables\/","name":"SQL plan directives on partitioned tables","isPartOf":{"@id":"https:\/\/nenadnoveljic.com\/blog\/#website"},"datePublished":"2015-10-14T19:53:27+00:00","dateModified":"2015-11-18T21:52:42+00:00","author":{"@id":"https:\/\/nenadnoveljic.com\/blog\/#\/schema\/person\/51458d9dd86dbbdd19f5add451d44efa"},"description":"SQL plan directives on partitioned tables with skewed data might cause worse cardinality estimates.","breadcrumb":{"@id":"https:\/\/nenadnoveljic.com\/blog\/sql-plan-directives-partitioned-tables\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/nenadnoveljic.com\/blog\/sql-plan-directives-partitioned-tables\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/nenadnoveljic.com\/blog\/sql-plan-directives-partitioned-tables\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/nenadnoveljic.com\/blog\/"},{"@type":"ListItem","position":2,"name":"SQL plan directives on partitioned tables"}]},{"@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\/48","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=48"}],"version-history":[{"count":2,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/posts\/48\/revisions"}],"predecessor-version":[{"id":531,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/posts\/48\/revisions\/531"}],"wp:attachment":[{"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/media?parent=48"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/categories?post=48"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/tags?post=48"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}