{"id":1745,"date":"2018-03-06T18:19:37","date_gmt":"2018-03-06T18:19:37","guid":{"rendered":"http:\/\/nenadnoveljic.com\/blog\/?p=1745"},"modified":"2021-09-02T15:21:49","modified_gmt":"2021-09-02T15:21:49","slug":"join-cardinality-misestimate","status":"publish","type":"post","link":"https:\/\/nenadnoveljic.com\/blog\/join-cardinality-misestimate\/","title":{"rendered":"JOIN CARDINALITY MISESTIMATE in Oracle 12.2"},"content":{"rendered":"<p>In this blog post I&#8217;ll be describing a case with wrong join cardinality estimation caused by adaptive dynamic sampling (DS). As indicated in the title, the issue has been introduced in the release 12.2.<\/p>\n<p>First of all, the test case is based on the assumption that optimizer_dynamic_sampling is set to 2:<\/p>\n<pre><code>NAME                                 TYPE        VALUE\n------------------------------------ ----------- ------------------------------\noptimizer_dynamic_sampling           integer     2<\/code><\/pre>\n<p>Also, before running the test I&#8217;m verifying that optimizer adaptive statistics have been enabled:<\/p>\n<pre><code>show parameter optimizer_adaptive_statistics\n\nNAME                                 TYPE        VALUE\n------------------------------------ ----------- ------------------------------\noptimizer_adaptive_statistics        boolean     TRUE<\/code><\/pre>\n<p>Then, I&#8217;m creating three tables &#8211; t1, t2 and t3.<\/p>\n<pre><code>create table t1 ( n1 number ) ;\n\ninsert into t1\n  select trunc(level\/4)+1\n    from dual connect by level &lt;= 320000 ;\ncommit ;\n\nexec dbms_stats.gather_table_stats( null, 'T1' ) ;\n\ncreate table t2 ( n1 number , n2 number ) ;    \ncreate table t3 ( n1 number , n2 number ) ;    \n\nexec dbms_stats.gather_table_stats( null, 'T2' ) ;\nexec dbms_stats.gather_table_stats( null, 'T3' ) ;\n\ninsert into t2\n  select level, level\n    from dual connect by level &lt;=150000 ;\n\ninsert into t3\n  select level, trunc(level\/3) \n    from dual connect by level &lt;=450000 ;\n\ncommit ;<\/code><\/pre>\n<p>It&#8217;s worth noting that I intentionally gathered statistics on the empty tables t2 and t3 <i>before<\/i> loading any data. By doing so, I&#8217;m misleading the optimizer to come up with wrong join cardinalities. As a consequence of this shameless manipulation, SQL plan directives (SPD) for DS will be created at the next execution, like for example:<\/p>\n<pre><code>--execute two times \nselect distinct t3.n1\nfrom t3 \n  join t2 on t3.n2 = t2.n2 \nwhere t2.n1 = 1  ;\n\nexec dbms_spd.flush_sql_plan_directive ;\n\nset long 1000\nSELECT type,reason, state, d.notes\n  FROM   dba_sql_plan_directives d, dba_sql_plan_dir_objects o\n  WHERE  d.directive_id=o.directive_id\n    AND  o.object_name in ( 'T2', 'T3' ) ;\n\nTYPE                    REASON                               STATE\n----------------------- ------------------------------------ ----------\nNOTES\n--------------------------------------------------------------------------------\nDYNAMIC_SAMPLING        SINGLE TABLE CARDINALITY MISESTIMATE USABLE\n&lt;spd_note&gt;\n  &lt;internal_state&gt;NEW&lt;\/internal_state&gt;\n  &lt;redundant&gt;NO&lt;\/redundant&gt;\n  &lt;spd_text&gt;{(TEST.T3)}&lt;\/spd_text&gt;\n&lt;\/spd_note&gt;\n\n<span style=\"color: #ff0000;\">DYNAMIC_SAMPLING        JOIN CARDINALITY MISESTIMATE<\/span>         USABLE\n&lt;spd_note&gt;\n  &lt;internal_state&gt;NEW&lt;\/internal_state&gt;\n  &lt;redundant&gt;NO&lt;\/redundant&gt;\n  &lt;spd_text&gt;&lt;<span style=\"color: #ff0000;\">{F(TEST.T2) - (TEST.T3)}<\/span>&lt;\/spd_text&gt;\n&lt;\/spd_note&gt;\n\nDYNAMIC_SAMPLING        JOIN CARDINALITY MISESTIMATE         USABLE\n&lt;spd_note&gt;\n  &lt;internal_state&gt;NEW&lt;\/internal_state&gt;\n  &lt;redundant&gt;NO&lt;\/redundant&gt;\n  &lt;spd_text&gt;{F(TEST.T2) - (TEST.T3)}&lt;\/spd_text&gt;\n&lt;\/spd_note&gt;<\/code><\/pre>\n<p>As you can see, SPDs for DS were indeed generated. As a matter of fact, the SPDs mentioned will kick in during the next execution inspite of the freshly updated statistics.<\/p>\n<pre><code>EXEC dbms_stats.gather_table_stats( null, 'T2' );\nEXEC dbms_stats.gather_table_stats( null, 'T3' );\n\nSELECT \/*+ gather_plan_statistics *\/ t3.n1\n  FROM t3 JOIN t2 ON t3.n2 = t2.n2\n  WHERE t2.n1 IN (SELECT \/*+ no_unnest *\/ n1 FROM t1 ) ;\n\n-----------------------------------------------------------------------------------------------------------------\n| Id  | Operation           | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |\n-----------------------------------------------------------------------------------------------------------------\n|   0 | SELECT STATEMENT    |      |      1 |        |    240K|00:06:03.69 |      54M|       |       |          |\n|*  1 |  FILTER             |      |      1 |        |    240K|00:06:03.69 |      54M|       |       |          |\n|*  2 |   HASH JOIN         |      |      1 |      <span style=\"color: #ff0000;\">1 |    449K<\/span>|00:00:00.49 |    1317 |  9268K|  2474K| 8131K (0)|\n|   3 |    TABLE ACCESS FULL| T2   |      1 |    150K|    150K|00:00:00.01 |     317 |       |       |          |\n|   4 |    TABLE ACCESS FULL| T3   |      1 |    450K|    450K|00:00:00.02 |     997 |       |       |          |\n|*  5 |   TABLE ACCESS FULL | T1   |    150K|      1 |  80271 |00:18:27.73 |      54M|       |       |          |\n-----------------------------------------------------------------------------------------------------------------\n\nPredicate Information (identified by operation id):\n---------------------------------------------------\n\n   1 - filter( IS NOT NULL)\n   2 - access(\"T3\".\"N2\"=\"T2\".\"N2\")\n   5 - filter(\"N1\"=:B1)\n\nNote\n-----\n   <span style=\"color: #ff0000;\">- dynamic statistics used: dynamic sampling (level=2)\n   - 1 Sql Plan Directive used for this statement<\/span><\/code><\/pre>\n<p>If you pay a closer attention to the estimated cardinality in the step 2 in the execution plan above, you&#8217;ll notice a huge discrepancy between the estimated and actual number of rows. What I mean by that is the optimizer estimated just one row while 449K were returned. In fact, a one-row estimation is often a cue for a completely wrong calculation.<\/p>\n<p>In contrast, this error doesn&#8217;t happen at all when DS is not being used:<\/p>\n<pre><code>-----------------------------------------------------------------------------------------------------------------\n| Id  | Operation           | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |\n-----------------------------------------------------------------------------------------------------------------\n|   0 | SELECT STATEMENT    |      |      1 |        |    240K|00:06:47.81 |      54M|       |       |          |\n|*  1 |  FILTER             |      |      1 |        |    240K|00:06:47.81 |      54M|       |       |          |\n|*  2 |   HASH JOIN         |      |      1 |    <span style=\"color: #ff0000;\">444K|    449K<\/span>|00:00:00.50 |    1320 |  9268K|  2474K| 8123K (0)|\n|   3 |    TABLE ACCESS FULL| T2   |      1 |    150K|    150K|00:00:00.01 |     317 |       |       |          |\n|   4 |    TABLE ACCESS FULL| T3   |      1 |    450K|    450K|00:00:00.02 |     997 |       |       |          |\n|*  5 |   TABLE ACCESS FULL | T1   |    150K|      1 |  80264 |00:18:13.30 |      54M|       |       |          |\n-----------------------------------------------------------------------------------------------------------------<\/code><\/pre>\n<p>But what exactly went on here?<\/p>\n<p>To answer this question I&#8217;m going to use information generated in two types of traces. One is the well-known CBO 10053 trace. The other is DS trace which I became aware of after having read <a href=\"https:\/\/blogs.sap.com\/2015\/06\/01\/oracle-db-optimizer-part-xii-revealing-sql-plan-directive-details-for-existingloaded-cursor-from-cbo-and-sql-dynamic-sampling-services-trace\/\">Stefan Koehler&#8217;s blog post<\/a>. So, this is how I activated both of the traces:<\/p>\n<pre><code>ALTER SESSION SET EVENTS 'trace[RDBMS.SQL_DS] disk=high';\nALTER SESSION SET EVENTS='10053 trace name context forever, level 1';<\/code><\/pre>\n<p>By looking at the trace file we can indeed confirm that DS produced a fairly accurate guess:<\/p>\n<pre><code>qksdsScaleResult(): Dumping scaled result (status = SUCCESS)\nqksdsDumpResult(): DS Results: #exps=1, smp obj=T3\nqksdsDumpResult():    T.CARD = qksdsDumpResult(): (mid=<span style=\"color: #ff0000;\">449810.0<\/span>, low=449810.0, hig=449810.0)qksdsDumpResult(): \nqksdsDumpResult(): end dumping results \n    SPD: qosdGetFObjKeyFromStmt: sqlText = SELECT \/* DS_SVC *\/ \/*+ dynamic_sampling(0) no_sql_tune no_monitoring optimizer_features_enable(default) no_parallel  *\/ NVL(SUM(C1),0) FROM (SELECT \/*+ qb_name(\"innerQuery\")&lt; NO_INDEX_FFS( \"T3#1\")  *\/ 1 AS C1 FROM \"T3\" \"T3#1\", \"T2\" \"T2#0\" WHERE (\"T3#1\".\"N2\"=\"T2#0\".\"N2\")) innerQuery (objid = 1800385981567557396)<\/code><\/pre>\n<p>As a matter of fact, it even generated a finding for future reference:<\/p>\n<pre>    SPD: Generating finding id: type = 2, reason = 7, objcnt = 3, obItr = 0, objid = 1800385981567557396, objtyp = 4, vecsize = 0, obItr = 1, objid = 94576, objtyp = 1, vecsize = 0, obItr = 2, objid = 94577, objtyp = 1, vecsize = 0, fid = 4662502719207033285\n    SPD: qosdCreateDir4DSResult retCode = CREATED, fid = 0<\/pre>\n<p>Furthermore, it can easily be verified that this finding is persisted as an SPD. Moreover, those newly created SPDs containing the result of DS will supersede the SPDs for DS itself, and in doing so completely eliminate DS in future optimizations:<\/p>\n<pre><code>SELECT type,reason, state, d.notes\n  FROM   dba_sql_plan_directives d, dba_sql_plan_dir_objects o\n  WHERE  d.directive_id=o.directive_id\n  4      AND  o.object_name in ( 'T2', 'T3' ) ;\n\nTYPE                    REASON                               STATE\n----------------------- ------------------------------------ ----------\nNOTES\n----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\nDYNAMIC_SAMPLING        SINGLE TABLE CARDINALITY MISESTIMATE USABLE\n&lt;spd_note&gt;\n  &lt;internal_state&gt;NEW&lt;\/internal_state&gt;\n  &lt;redundant&gt;NO&lt;\/redundant&gt;\n  &lt;spd_text&gt;{(TEST.T3)}&lt;\/spd_text&gt;\n&lt;\/spd_note&gt;\n\nDYNAMIC_SAMPLING        JOIN CARDINALITY MISESTIMATE         SUPERSEDED\n&lt;spd_note&gt;\n  &lt;internal_state&gt;HAS_STATS&lt;\/internal_state&gt;\n  &lt;redundant&gt;NO&lt;\/redundant&gt;\n  &lt;spd_text&gt;{F(TEST.T2) - (TEST.T3)}&lt;\/spd_text&gt;\n&lt;\/spd_note&gt;\n\n<span style=\"color: #ff0000;\">DYNAMIC_SAMPLING        JOIN CARDINALITY MISESTIMATE         SUPERSEDED<\/span>\n&lt;spd_note&gt;\n  &lt;internal_state&gt;HAS_STATS&lt;\/internal_state&gt;\n  &lt;redundant&gt;NO&lt;\/redundant&gt;\n  &lt;spd_text&gt;{F(TEST.T2) - (TEST.T3)}&lt;\/spd_text&gt;\n&lt;\/spd_note&gt;\n\n<span style=\"color: #ff0000;\">DYNAMIC_SAMPLING_RESULT VERIFY CARDINALITY ESTIMATE          USABLE<\/span>\n&lt;spd_note&gt;\n  &lt;internal_state&gt;NEW&lt;\/internal_state&gt;\n  &lt;redundant&gt;NO&lt;\/redundant&gt;\n  &lt;spd_text&gt;{(TEST.T2, num_rows=150000) - (TEST.T3, num_rows=450000) - (SQL_ID:1jz21hbnyursn, \nT.CARD=<span style=\"color: #ff0000;\">450347<\/span>[-2 -2])}&lt;\/spd_text&gt;\n&lt;\/spd_note&gt;\n\nDYNAMIC_SAMPLING_RESULT VERIFY CARDINALITY ESTIMATE          USABLE\n&lt;spd_note&gt;\n  &lt;internal_state&gt;NEW&lt;\/internal_state&gt;\n  &lt;redundant&gt;NO&lt;\/redundant&gt;\n  &lt;spd_text&gt;{(TEST.T2, num_rows=150000) - (TEST.T3, num_rows=450000) - (SQL_ID:1jz21hbnyursn, \nT.CARD=450347[-2 -2])}&lt;\/spd_text&gt;\n&lt;\/spd_note&gt;&lt;\/code&gt;&lt;\/pre&gt;<\/code><\/pre>\n<p>Anyway, given the optimizer estimated the cardinality perfectly and those estimates are successfully being applied to the subsequent executions, the following question inevitably arises:<\/p>\n<p>What went wrong with the on-going optimization process?<\/p>\n<p>We can find a cue by further examining the trace:<\/p>\n<pre><code>&gt;&gt; <span style=\"color: #ff0000;\">Join Card adjusted from 444734.345351 to 0.000000 due to adaptive dynamic sampling<\/span>, prelen=2\nAdjusted Join Cards: adjRatio=0.000000 cardHjSmj=0.000000 cardHjSmjNPF=0.000000 cardNlj=0.000000 cardNSQ=0.000000 cardNSQ_na=444734.345351\nJoin Card - Rounded: 1 Computed: 0.000000<\/code><\/pre>\n<p>Surprisingly, the cardinality was adjusted to zero after DS, which explains the estimated cardinality of &#8220;1&#8221; in the execution plan. In my opinion, it is a bug. However, I couldn&#8217;t find any information on Metalink about it.<\/p>\n<p>As far as previous releases are concerned, the same test case runs correctly on 12.1. The main difference between both releases with regard to this issue is that 12.2 persists estimated cardinalities after doing DS (see <a href=\"https:\/\/mauro-pagano.com\/2016\/11\/28\/something-new-about-sql-plan-directives-and-12-2\/\">Mauro Pagano&#8217;s blog posts<\/a> for more information). It is undoubtedly a significant enhancement compared to the previous release, where the information was stored in the result cache. Unfortunately, some boundary conditions apparently haven&#8217;t been handled properly since implementing this change. Consequently, you might observe some catastrophically wrong join cardinality estimates (and bad execution plans too) when dynamic sampling is performed.<\/p>\n<h1>Updates<\/h1>\n<h2>March 20, 2018<\/h2>\n<h3>More Realistic Test Case<\/h3>\n<p>Meanwhile, I published <a href=\"http:\/\/nenadnoveljic.com\/blog\/join-cardinality-misestimate-adjustment-to-zero-issue-in-oracle-12-2-part-2\/\">another test case<\/a> which is a bit closer to reality. As you can see there, the execution plan changes for the better with the second execution. Also, the difference between the good and the bad plan is dramatic. Besides that, I reengineered the test case, so that no hint is used any more to prevent unnesting. Instead, the optimizer decides himself not to do the transformation as a result of a wrong cardinality estimate which, in turn, is caused by the adjustment-to-zero issue.<\/p>\n<h3>Workaround<\/h3>\n<p>The problem was apparently introduced with the bug fix &#8220;22817465 : AUTODOP CALCULATES DOP OF 1 FOR SPECIFIC QUERY&#8221;. So, switching off the bug fix resolves the issue:<\/p>\n<pre><code>alter session set \"_fix_control\"='21802552:off';\n\n-----------------------------------------------------------------------------------------------------------------\n| Id  | Operation           | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |\n-----------------------------------------------------------------------------------------------------------------\n|   0 | SELECT STATEMENT    |      |      1 |        |    240K|00:06:35.51 |      54M|       |       |          |\n|*  1 |  FILTER             |      |      1 |        |    240K|00:06:35.51 |      54M|       |       |          |\n|*  2 |   HASH JOIN         |      |      1 |    <span style=\"color: #ff0000;\">458K|    449K<\/span>|00:00:00.50 |    1295 |  9268K|  2474K| 8130K (0)|\n|   3 |    TABLE ACCESS FULL| T2   |      1 |    150K|    150K|00:00:00.01 |     314 |       |       |          |\n|   4 |    TABLE ACCESS FULL| T3   |      1 |    450K|    450K|00:00:00.02 |     978 |       |       |          |\n|*  5 |   TABLE ACCESS FULL | T1   |    150K|      1 |  80001 |00:19:23.80 |      54M|       |       |          |\n-----------------------------------------------------------------------------------------------------------------<\/code><\/pre>\n<p>Also, it can be easily verified by looking at the optimizer trace that the adjustement now is being done correctly:<\/p>\n<pre><code>Join Card adjusted from 444734.345351 to <span style=\"color: #ff0000;\">458393.000000<\/span> due to adaptive dynamic sampling, prelen=2<\/code><\/pre>\n<p>Big thanks to Nigel Bayliss, the product manager for the Oracle Optimizer, for reaching out after reading this blog post and persevering in finding out the root cause and the workaround.<\/p>\n<h2>Bug number &#8211; May 9, 2018<\/h2>\n<p>The following bug has been raised for the problem: Bug 27989222 : WRONG CARDINALITY ESTIMATION WITH STALE DIRECTIVES WHEN FIX 21802552 IS ENABLED.<\/p>\n<h2>Workaround side-effects &#8211; July 5, 2019<\/h2>\n<p>I changed &#8220;alter system&#8221; to &#8220;alter session&#8221; in the workaround, as switching off the fix globally can produce side-effects elsewhere. Thanks to <a href=\"https:\/\/jolliffe.hk\/\">Patrick Jolliffe<\/a> for pointing that out.<br \/>\nOf course, you can also set it only for a SQL by hint.<\/p>\n<h2>19c &#8211; October 28, 2020<\/h2>\n<p>The bug ist still here &#8211; tested on 19.7.0.0.200414. Continue to be careful with the workaround, as it can cause problems elsewhere. We switched off the bug fix 21802552 globally and have been enabling it on a case-by-case basis.<\/p>\n<h2>21c &#8211; September 2, 2021<\/h2>\n<p>The bug isn&#8217;t fixed yet.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Wrong join cardinality estimate due to adaptive dynamic sampling <a href=\"https:\/\/nenadnoveljic.com\/blog\/join-cardinality-misestimate\/\" 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":[22,10,11,5],"tags":[],"class_list":["post-1745","post","type-post","status-publish","format-standard","hentry","category-12-2","category-adaptive-query-optimization","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>JOIN CARDINALITY MISESTIMATE in Oracle 12.2 - All-round Database Topics<\/title>\n<meta name=\"description\" content=\"Wrong join cardinality estimate due to adaptive dynamic sampling\" \/>\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\/join-cardinality-misestimate\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"JOIN CARDINALITY MISESTIMATE in Oracle 12.2 - All-round Database Topics\" \/>\n<meta property=\"og:description\" content=\"Wrong join cardinality estimate due to adaptive dynamic sampling\" \/>\n<meta property=\"og:url\" content=\"https:\/\/nenadnoveljic.com\/blog\/join-cardinality-misestimate\/\" \/>\n<meta property=\"og:site_name\" content=\"All-round Database Topics\" \/>\n<meta property=\"article:published_time\" content=\"2018-03-06T18:19:37+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-09-02T15:21:49+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=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/join-cardinality-misestimate\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/join-cardinality-misestimate\\\/\"},\"author\":{\"name\":\"Nenad Noveljic\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/#\\\/schema\\\/person\\\/51458d9dd86dbbdd19f5add451d44efa\"},\"headline\":\"JOIN CARDINALITY MISESTIMATE in Oracle 12.2\",\"datePublished\":\"2018-03-06T18:19:37+00:00\",\"dateModified\":\"2021-09-02T15:21:49+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/join-cardinality-misestimate\\\/\"},\"wordCount\":838,\"commentCount\":1,\"articleSection\":[\"12.2\",\"adaptive query optimization\",\"cost based optimizer\",\"Oracle\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/join-cardinality-misestimate\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/join-cardinality-misestimate\\\/\",\"url\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/join-cardinality-misestimate\\\/\",\"name\":\"JOIN CARDINALITY MISESTIMATE in Oracle 12.2 - All-round Database Topics\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/#website\"},\"datePublished\":\"2018-03-06T18:19:37+00:00\",\"dateModified\":\"2021-09-02T15:21:49+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/#\\\/schema\\\/person\\\/51458d9dd86dbbdd19f5add451d44efa\"},\"description\":\"Wrong join cardinality estimate due to adaptive dynamic sampling\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/join-cardinality-misestimate\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/join-cardinality-misestimate\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/join-cardinality-misestimate\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"JOIN CARDINALITY MISESTIMATE in Oracle 12.2\"}]},{\"@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":"JOIN CARDINALITY MISESTIMATE in Oracle 12.2 - All-round Database Topics","description":"Wrong join cardinality estimate due to adaptive dynamic sampling","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\/join-cardinality-misestimate\/","og_locale":"en_US","og_type":"article","og_title":"JOIN CARDINALITY MISESTIMATE in Oracle 12.2 - All-round Database Topics","og_description":"Wrong join cardinality estimate due to adaptive dynamic sampling","og_url":"https:\/\/nenadnoveljic.com\/blog\/join-cardinality-misestimate\/","og_site_name":"All-round Database Topics","article_published_time":"2018-03-06T18:19:37+00:00","article_modified_time":"2021-09-02T15:21:49+00:00","author":"Nenad Noveljic","twitter_card":"summary_large_image","twitter_creator":"@NenadNoveljic","twitter_misc":{"Written by":"Nenad Noveljic","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/nenadnoveljic.com\/blog\/join-cardinality-misestimate\/#article","isPartOf":{"@id":"https:\/\/nenadnoveljic.com\/blog\/join-cardinality-misestimate\/"},"author":{"name":"Nenad Noveljic","@id":"https:\/\/nenadnoveljic.com\/blog\/#\/schema\/person\/51458d9dd86dbbdd19f5add451d44efa"},"headline":"JOIN CARDINALITY MISESTIMATE in Oracle 12.2","datePublished":"2018-03-06T18:19:37+00:00","dateModified":"2021-09-02T15:21:49+00:00","mainEntityOfPage":{"@id":"https:\/\/nenadnoveljic.com\/blog\/join-cardinality-misestimate\/"},"wordCount":838,"commentCount":1,"articleSection":["12.2","adaptive query optimization","cost based optimizer","Oracle"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/nenadnoveljic.com\/blog\/join-cardinality-misestimate\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/nenadnoveljic.com\/blog\/join-cardinality-misestimate\/","url":"https:\/\/nenadnoveljic.com\/blog\/join-cardinality-misestimate\/","name":"JOIN CARDINALITY MISESTIMATE in Oracle 12.2 - All-round Database Topics","isPartOf":{"@id":"https:\/\/nenadnoveljic.com\/blog\/#website"},"datePublished":"2018-03-06T18:19:37+00:00","dateModified":"2021-09-02T15:21:49+00:00","author":{"@id":"https:\/\/nenadnoveljic.com\/blog\/#\/schema\/person\/51458d9dd86dbbdd19f5add451d44efa"},"description":"Wrong join cardinality estimate due to adaptive dynamic sampling","breadcrumb":{"@id":"https:\/\/nenadnoveljic.com\/blog\/join-cardinality-misestimate\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/nenadnoveljic.com\/blog\/join-cardinality-misestimate\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/nenadnoveljic.com\/blog\/join-cardinality-misestimate\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/nenadnoveljic.com\/blog\/"},{"@type":"ListItem","position":2,"name":"JOIN CARDINALITY MISESTIMATE in Oracle 12.2"}]},{"@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\/1745","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=1745"}],"version-history":[{"count":1,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/posts\/1745\/revisions"}],"predecessor-version":[{"id":3901,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/posts\/1745\/revisions\/3901"}],"wp:attachment":[{"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/media?parent=1745"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/categories?post=1745"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/tags?post=1745"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}