{
  "date": "2015-05-18T13:17:21",
  "slug": "matching-sql-plan-directives-and-queries-using-it",
  "link": "https://www.dbi-services.com/blog/matching-sql-plan-directives-and-queries-using-it/",
  "title": {
    "rendered": "Matching SQL Plan Directives and queries using it"
  },
  "content": {
    "rendered": "<h2>By Franck Pachot</h2>\n<p>.<br />\nThis is another blog post I&#8217;m writing while reviewing the presentation I&#8217;m doing next week for<a href=\"https://www.dbi-services.com/index.php/blog/entry/matching-sql-plan-directives-and-extended-stats-\">SOUG</a> and next month for <a href=\"http://www.doag.org/events/konferenzen/doag-2015-datenbank.html\">DOAG</a>. You have SQL Plan Directives used by several queries that have same kind of predicates. And queries that can use several SPD. Can you match them?</p>\n<p>When a query uses a SPD (meaning that the SPD in usable state &#8211; NEW, MISSING_STATS or PERMANENT internal state) the execution plan show it as:</p>\n<pre><code>Note\n-----\n   - dynamic statistics used: dynamic sampling (level=2)\n   - 1 Sql Plan Directive used for this statement\n</code></pre>\n<p>but you don&#8217;t have information about which directive(s).</p>\n<p>Unfortunately that information is not stored in V$SQL_PLAN information. There are two ways to get information:</p>\n<ul>\n<li>Parse it and trace it with set events &#8216;trace [SQL_Plan_Directive.*]&#8217; but that&#8217;s for another post.</li>\n<li>Do an EXPLAIN PLAN and info is in PLAN_TABLE.OTHER_XML</li>\n</ul>\n<h3>example</h3>\n<p>Here are the SQL Plan Directives I have:</p>\n<pre><code>SQL&gt; select directive_id,type,state,reason,notes,created,last_modified,last_used from dba_sql_plan_d\nirectives where directive_id in( select directive_id from dba_sql_plan_dir_objects where owner='DEMO\n' ) order by created;\n\n           DIRECTIVE_ID TYPE             STATE      REASON\n----------------------- ---------------- ---------- ------------------------------------\nNOTES                                                                                      CREATED\n------------------------------------------------------------------------------------------ --------\nLAST_MOD LAST_USE\n-------- --------\n   11092019653200552215 DYNAMIC_SAMPLING SUPERSEDED SINGLE TABLE CARDINALITY MISESTIMATE\n.spd_note.                                                                                 21:21:58\n  .internal_state.HAS_STATS./internal_state.\n  .redundant.NO./redundant.\n  .spd_text.{EC(DEMO.DEMO_TABLE)[A, B, C, D]}./spd_text.\n./spd_note.\n21:30:09 21:30:09\n\n    9695481911885124390 DYNAMIC_SAMPLING USABLE     SINGLE TABLE CARDINALITY MISESTIMATE\n.spd_note.                                                                                 21:35:45\n  .internal_state.NEW./internal_state.\n  .redundant.NO./redundant.\n  .spd_text.{E(DEMO.DEMO_TABLE)[A, B, C, D]}./spd_text.\n./spd_note.\n</code></pre>\n<p><i>(I changed the xml tag because our current blog platform is a bit creative with them&#8230; fortunately we are migrating soon to wordpress)</i></p>\n<h3>+metrics</h3>\n<p>So in order to have more information, you have to re-parse the statement with EXPLAIN PLAN FOR&#8230; and show it with DBMS_XPLAN.DISPLAY witht he format &#8216;+METRICS&#8217;</p>\n<pre><code>SQL&gt; explain plan for select * from DEMO_TABLE where a+b=c+d;\n\nExplained.\n</code></pre>\n<p>This query will use the {E(DEMO.DEMO_TABLE)[A, B, C, D]} directive but not the {EC(DEMO.DEMO_TABLE)[A, B, C, D]} one because it&#8217;s not simple columns predicates.<br />\nLet&#8217;s get the execution plan from PLAN_TABLE with the +METRICS format:</p>\n<pre><code>SQL&gt; select * from table(dbms_xplan.display(null,null,'+metrics'));\n\nPLAN_TABLE_OUTPUT\n----------------------------------------------------------------------------------------------------\nPlan hash value: 4063024151\n\n--------------------------------------------------------------------------------\n| Id  | Operation         | Name       | Rows  | Bytes | Cost (%CPU)| Time     |\n--------------------------------------------------------------------------------\n|   0 | SELECT STATEMENT  |            |  1000 | 12000 |     3   (0)| 00:00:01 |\n|*  1 |  TABLE ACCESS FULL| DEMO_TABLE |  1000 | 12000 |     3   (0)| 00:00:01 |\n--------------------------------------------------------------------------------\n\nPredicate Information (identified by operation id):\n---------------------------------------------------\n\n   1 - filter(\"A\"+\"B\"=\"C\"+\"D\")\n\nSql Plan Directive information:\n-------------------------------\n\n  Used directive ids:\n    9695481911885124390\n\nNote\n-----\n   - dynamic statistics used: dynamic sampling (level=2)\n   - 1 Sql Plan Directive used for this statement\n\n</code></pre>\n<p>As you can see, in addition to the number of SPD used you have the DIRECTIVE ID.</p>\n<h3>Conclusion</h3>\n<p>It&#8217;s not easy to match all queries that can use a SQL Plan Directive, but you can do it on the other way: do an explain plan for each query you suspect and check the notes. If you are ready to parse a lot of queries, you can also do it automatically.</p>\n",
    "protected": false
  }
}
