{"id":73307,"date":"2012-06-20T15:07:50","date_gmt":"2012-06-20T15:07:50","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/uncategorized\/dynamic-sampling-iii-real-life-data-part-i\/"},"modified":"2021-07-14T13:07:56","modified_gmt":"2021-07-14T13:07:56","slug":"dynamic-sampling-iii-real-life-data-part-i","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/databases\/oracle-databases\/dynamic-sampling-iii-real-life-data-part-i\/","title":{"rendered":"Dynamic Sampling (III) &#8211; Real-Life Data &#8211; Part I"},"content":{"rendered":"<p>In the <a title=\"Dynamic Sampling (I), an Introduction \u2013 Part 1\" href=\"https:\/\/allthingsoracle.com\/dynamic-sampling-i-an-introduction-part-1\/\" target=\"_blank\">previous<\/a> <a title=\"Dynamic Sampling (II) \u2013 Controlling the Activity \u2013 Part 1\" href=\"https:\/\/allthingsoracle.com\/dynamic-sampling-ii-controlling-the-activity-part-1\/\" target=\"_blank\">parts<\/a> of the series I outlined the basics on Dynamic Sampling. Let&#8217;s see how Dynamic Sampling deals with typical real-life data patterns.<\/p>\n<p>As you might be aware, quite often real data follows certain patterns for how data is clustered together, usually related to how the data arrives. This <strong>clustering (or scattering) of data<\/strong> within a table can be influenced by the physical organisation of the table, but in the most commonly used <strong>Heap Organized Table<\/strong> in Oracle the data can be stored generally in any table block and hence usually follows the <strong>natural pattern<\/strong> dictated by the <strong>data arrival<\/strong>.<\/p>\n<p>Furthermore quite often the most interesting data is the <strong>latest data<\/strong>, and the data your queries might be interested in\u00a0is\u00a0usually not spread randomly across the table, but <strong>clustered together<\/strong> in a specific area of the table.<\/p>\n<p>If you think about how Dynamic Sampling works by <strong>randomly sampling &#8211;\u00a0<\/strong>usually only a very <strong>limited number of blocks<\/strong> (commonly something between 32 and 256 blocks) &#8211; then it might become obvious that problems dealing with such clustered data patterns can arise, because very likely the few blocks sampled won&#8217;t contain a <strong>representative<\/strong> sub-set of the data we are looking for.<\/p>\n<p>This means that Dynamic Sampling works well if the data you&#8217;re looking for is <strong>spread randomly across a table<\/strong>, but by default has problems when the data you&#8217;re looking for is either <strong>clustered together<\/strong> or simply<strong> very rare<\/strong>. In both cases chances are high that the blocks sampled don&#8217;t contain a representative sub-set of the data you&#8217;re looking for, and the <strong>sanity checks<\/strong> built into the code will then kick in and <strong>reject<\/strong> the Dynamic Sampling results.<\/p>\n<p>Let&#8217;s see a simple test case for how Dynamic Sampling deals with such a data pattern.<\/p>\n<h2>The Baseline<\/h2>\n<p>What I simulate here is a typical problem of <strong>correlated column values<\/strong> &#8211; I&#8217;m looking for the <strong>most recent data<\/strong> that is in a certain status that represents <strong>&#8220;unprocessed&#8221;<\/strong> data. Of course, it is very likely that the most recent data is the data that is yet to be processed, so these <strong>two questions<\/strong> basically ask for the <strong>same information<\/strong>, but in two different ways.<\/p>\n<p>The example is based on the &#8220;parcels&#8221; example Jonathan Lewis used in his &#8220;Statistics&#8221; chapter of the book &#8220;Expert Oracle Practices&#8221; (used with permission).<\/p>\n<pre>create table parcels\r\nas\r\nwith generator as (\r\nselect  --+ materialize\r\n        rownum as id\r\nfrom\r\n        all_objects\r\nwhere\r\n        rownum &lt;= 3000\r\n)\r\nselect\r\n        rownum                                     as id\r\n      , sysdate - trunc((1000000 - rownum)\/1000,2) as pickup_date\r\n      , case\r\n          when rownum &gt; 999000\r\n          then 'In-transit'\r\n          else 'Delivered'\r\n        end                                        as delivery_status\r\n      , lpad(rownum,10)                            as small_vc\r\n      , lpad('x',150)                              as padding\r\nfrom\r\n        generator v1\r\n      , generator v2\r\nwhere\r\n        rownum &lt;= 1000000\r\n;\r\n\r\nexec dbms_stats.gather_table_stats(null, 'parcels', method_opt =&gt; 'for all columns size 1 for columns delivery_status size 2')<\/pre>\n<p>There are <strong>1,000<\/strong> parcels <strong>per day<\/strong> for the <strong>last 1,000 days<\/strong>, and the last 1,000 parcels are marked as <strong>&#8220;In-transit&#8221;<\/strong>.<\/p>\n<p>We are looking for a good cardinality estimate for the following query:<\/p>\n<pre>select\r\n        *\r\nfrom\r\n        parcels pcl\r\nwhere\r\n        pcl.pickup_date &gt;= sysdate - 1\r\nand     pcl.delivery_status = 'In-transit'<\/pre>\n<p>So both filter predicates identify <strong>1,000 rows<\/strong> each out of 1,000,000 and since I have generated a <strong>histogram<\/strong> on the <strong>highly skewed<\/strong> &#8220;delivery_status&#8221; column the optimizer is aware of this. Applying the predicates <strong>independently<\/strong> from each other shows that the optimizer&#8217;s estimates are in the right ballpark.<\/p>\n<p>The problem however is that applying both together by default results in an estimate of <strong>1 out 1,000,000<\/strong> since the optimizer doesn&#8217;t know about the <strong>correlation<\/strong>.<\/p>\n<pre>explain plan for\r\nselect\r\n        *\r\nfrom\r\n        parcels pcl\r\nwhere\r\n        pcl.pickup_date &gt;= sysdate - 1\r\n;\r\n\r\nselect * from table(dbms_xplan.display);\r\n\r\n-----------------------------------------------------------------------------\r\n| Id\u00a0 | Operation\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | Name\u00a0\u00a0\u00a0 | Rows\u00a0 | Bytes | Cost (%CPU)| Time\u00a0\u00a0\u00a0\u00a0 |\r\n-----------------------------------------------------------------------------\r\n|\u00a0\u00a0 0 | SELECT STATEMENT\u00a0 |\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 |\u00a0 1003 |\u00a0\u00a0 181K|\u00a0 7305\u00a0\u00a0 (2)| 00:01:28 |\r\n|*\u00a0 1 |\u00a0 TABLE ACCESS FULL| PARCELS |\u00a0 <span style=\"color: #ff0000;\"><strong>1003<\/strong><\/span> |\u00a0\u00a0 181K|\u00a0 7305\u00a0\u00a0 (2)| 00:01:28 |\r\n-----------------------------------------------------------------------------\r\n\r\nPredicate Information (identified by operation id):\r\n---------------------------------------------------\r\n\r\n   1 - filter(\"PCL\".\"PICKUP_DATE\"&gt;=SYSDATE@!-1)\r\n\r\nexplain plan for\r\nselect\r\n        *\r\nfrom\r\n        parcels pcl\r\nwhere\r\n        pcl.delivery_status = 'In-transit'\r\n;\r\n\r\nselect * from table(dbms_xplan.display);\r\n\r\n-----------------------------------------------------------------------------\r\n| Id\u00a0 | Operation\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | Name\u00a0\u00a0\u00a0 | Rows\u00a0 | Bytes | Cost (%CPU)| Time\u00a0\u00a0\u00a0\u00a0 |\r\n-----------------------------------------------------------------------------\r\n|\u00a0\u00a0 0 | SELECT STATEMENT\u00a0 |\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 |\u00a0\u00a0 828 |\u00a0\u00a0 149K|\u00a0 7231\u00a0\u00a0 (1)| 00:01:27 |\r\n|*\u00a0 1 |\u00a0 TABLE ACCESS FULL| PARCELS |\u00a0\u00a0 <span style=\"color: #ff0000;\"><strong>828<\/strong><\/span> |\u00a0\u00a0 149K|\u00a0 7231\u00a0\u00a0 (1)| 00:01:27 |\r\n-----------------------------------------------------------------------------\r\n\r\nPredicate Information (identified by operation id):\r\n---------------------------------------------------\r\n\r\n   1 - filter(\"PCL\".\"DELIVERY_STATUS\"='In-transit')\r\n\r\nexplain plan for\r\nselect\r\n        *\r\nfrom\r\n        parcels pcl\r\nwhere\r\n        pcl.pickup_date &gt;= sysdate - 1\r\nand     pcl.delivery_status = 'In-transit'\r\n;\r\n\r\nselect * from table(dbms_xplan.display);\r\n\r\n-----------------------------------------------------------------------------\r\n| Id\u00a0 | Operation\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | Name\u00a0\u00a0\u00a0 | Rows\u00a0 | Bytes | Cost (%CPU)| Time\u00a0\u00a0\u00a0\u00a0 |\r\n-----------------------------------------------------------------------------\r\n|\u00a0\u00a0 0 | SELECT STATEMENT\u00a0 |\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 |\u00a0\u00a0\u00a0\u00a0 1 |\u00a0\u00a0 185 |\u00a0 7231\u00a0\u00a0 (1)| 00:01:27 |\r\n|*\u00a0 1 |\u00a0 TABLE ACCESS FULL| PARCELS |\u00a0\u00a0\u00a0\u00a0 <strong><span style=\"color: #ff0000;\">1<\/span><\/strong> |\u00a0\u00a0 185 |\u00a0 7231\u00a0\u00a0 (1)| 00:01:27 |\r\n-----------------------------------------------------------------------------\r\n\r\nPredicate Information (identified by operation id):\r\n---------------------------------------------------\r\n\r\n   1 - filter(\"PCL\".\"DELIVERY_STATUS\"='In-transit' AND \"PCL\".\"PICKUP_DATE\"&gt;=SYSDATE@!-1)<\/pre>\n<p>Since one of the predicates is based on a <strong>non-equal comparison<\/strong> the new <strong>&#8220;Extended Statistics&#8221;<\/strong> of 11g is of no help either, since it works for column groups only if all filters on the column group are based on equal comparisons.<\/p>\n<p>So we are left with Dynamic Sampling. At the session <strong>default level of 2<\/strong> Dynamic Sampling won&#8217;t kick in. We need to either <strong>increase<\/strong> the session\/cursor level (according to the level descriptions,\u00a0<strong>level 4<\/strong> or higher sound reasonable for correlated column values), or we could ask for an explicit table level Dynamic Sampling. Remember that the number of blocks sampled is defined <strong>differently<\/strong> for the &#8220;session\/cursor&#8221; and &#8220;table&#8221; level Dynamic Sampling (as explained in the <a title=\"Dynamic Sampling (II) \u2013 Controlling the Activity \u2013 Part 1\" href=\"https:\/\/allthingsoracle.com\/dynamic-sampling-ii-controlling-the-activity-part-1\/\" target=\"_blank\">previous parts<\/a> of this series).<\/p>\n<p>Let&#8217;s start with session level Dynamic Sampling set to level 4:<\/p>\n<pre>set echo on\r\n\r\nalter session set tracefile_identifier = 'dyn_samp';\r\n\r\nalter session set optimizer_dynamic_sampling = 4;\r\n\r\nalter session set events '10053 trace name context forever, level 1';\r\n\r\nexplain plan for\r\nselect\r\n        *\r\nfrom\r\n        parcels pcl\r\nwhere\r\n        pcl.pickup_date &gt;= sysdate - 1\r\nand     pcl.delivery_status = 'In-transit'\r\n;\r\n\r\nselect * from table(dbms_xplan.display);\r\n\r\n-----------------------------------------------------------------------------\r\n| Id\u00a0 | Operation\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | Name\u00a0\u00a0\u00a0 | Rows\u00a0 | Bytes | Cost (%CPU)| Time\u00a0\u00a0\u00a0\u00a0 |\r\n-----------------------------------------------------------------------------\r\n|\u00a0\u00a0 0 | SELECT STATEMENT\u00a0 |\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 |\u00a0\u00a0\u00a0\u00a0 1 |\u00a0\u00a0 185 |\u00a0 7231\u00a0\u00a0 (1)| 00:01:27 |\r\n|*\u00a0 1 |\u00a0 TABLE ACCESS FULL| PARCELS |\u00a0\u00a0\u00a0\u00a0 <span style=\"color: #ff0000;\"><strong>1<\/strong><\/span> |\u00a0\u00a0 185 |\u00a0 7231\u00a0\u00a0 (1)| 00:01:27 |\r\n-----------------------------------------------------------------------------\r\n\r\nPredicate Information (identified by operation id):\r\n---------------------------------------------------\r\n\r\n   1 - filter(\"PCL\".\"DELIVERY_STATUS\"='In-transit' AND \"PCL\".\"PICKUP_DATE\"&gt;=SYSDATE@!-1)<\/pre>\n<p>As expected and already outlined above that didn&#8217;t really help. There is no notice of Dynamic Sampling in the <strong>DBMS_XPLAN.DISPLAY<\/strong> output, although we would expect Dynamic Sampling to kick in under these circumstances.<\/p>\n<p>Let&#8217;s have a look at the optimizer trace file:<\/p>\n<pre>** Dynamic sampling initial checks returning TRUE (<span style=\"color: #ff0000;\"><strong>level = 4<\/strong><\/span>).\r\n\r\n*** 2012-05-29 09:10:29.423\r\n** Generated dynamic sampling query:\r\nquery text :\r\nSELECT \/* OPT_DYN_SAMP *\/ \/*+ ALL_ROWS IGNORE_WHERE_CLAUSE NO_PARALLEL(SAMPLESUB) opt_param('parallel_execution_enabled', 'false') NO_PARALLEL_INDEX(SAMPLESUB) NO_SQL_TUNE *\/ NVL(SUM(C1),0), NVL(SUM(C2),0) FROM (SELECT \/*+ IGNORE_WHERE_CLAUSE NO_PARALLEL(\"PCL\") FULL(\"PCL\") NO_PARALLEL_INDEX(\"PCL\") *\/ 1 AS C1, CASE WHEN \"PCL\".\"PICKUP_DATE\"&gt;=SYSDATE@!-1 AND \"PCL\".\"DELIVERY_STATUS\"='In-transit' THEN 1 ELSE 0 END AS C2 FROM \"PARCELS\" SAMPLE BLOCK (0.116902 , 1) SEED (1) \"PCL\") SAMPLESUB\r\n\r\n*** 2012-05-29 09:10:29.423\r\n** Executed dynamic sampling query:\r\nlevel : 4\r\nsample pct. : 0.116902\r\n<span style=\"color: #ff0000;\"><strong>actual sample size : 912<\/strong><\/span>\r\n<span style=\"color: #ff0000;\"><strong>filtered sample card. : 0<\/strong><\/span>\r\norig. card. : 1000000\r\nblock cnt. table stat. : 26518\r\nblock cnt. for sampling: 26518\r\nmax. sample block cnt. : 32\r\n<span style=\"color: #ff0000;\"><strong>sample block cnt. : 31<\/strong><\/span>\r\nmin. sel. est. : 0.00000083\r\n<span style=\"color: #ff0000;\"><strong>** Not using dynamic sampling for single table sel. or cardinality.<\/strong><\/span>\r\nDS Failed for : ----- Current SQL Statement for this session (sql_id=bzacaa129jp2q) -----<\/pre>\n<p>So Dynamic Sampling was performed, but the result was <strong>rejected<\/strong> due to the fact that the sample size was just 31 blocks and no positive samples were found.<\/p>\n<p>Another try with a higher level that results in a greater sample size, session level 8 in this case:<\/p>\n<pre>** Dynamic sampling initial checks returning TRUE (<span style=\"color: #ff0000;\"><strong>level = 8<\/strong><\/span>).\r\n\r\n*** 2012-05-29 18:39:56.560\r\n** Generated dynamic sampling query:\r\nquery text :\r\nSELECT \/* OPT_DYN_SAMP *\/ \/*+ ALL_ROWS IGNORE_WHERE_CLAUSE NO_PARALLEL(SAMPLESUB) opt_param('parallel_execution_enabled', 'false') NO_PARALLEL_INDEX(SAMPLESUB) NO_SQL_TUNE *\/ NVL(SUM(C1),0), NVL(SUM(C2),0) FROM (SELECT \/*+ IGNORE_WHERE_CLAUSE NO_PARALLEL(\"PCL\") FULL(\"PCL\") NO_PARALLEL_INDEX(\"PCL\") *\/ 1 AS C1, CASE WHEN \"PCL\".\"PICKUP_DATE\"&gt;=SYSDATE@!-1 AND \"PCL\".\"DELIVERY_STATUS\"='In-transit' THEN 1 ELSE 0 END AS C2 FROM \"PARCELS\" SAMPLE BLOCK (3.857757 , 1) SEED (1) \"PCL\") SAMPLESUB\r\n\r\n*** 2012-05-29 18:39:57.246\r\n** Executed dynamic sampling query:\r\nlevel : 8\r\nsample pct. : 3.857757\r\n<span style=\"color: #ff0000;\"><strong>actual sample size : 36972<\/strong><\/span>\r\n<span style=\"color: #ff0000;\"><strong>filtered sample card. : 0<\/strong><\/span>\r\norig. card. : 1000000\r\nblock cnt. table stat. : 26518\r\nblock cnt. for sampling: 26518\r\nmax. sample block cnt. : 1024\r\n<span style=\"color: #ff0000;\"><strong>sample block cnt. : 1023<\/strong><\/span>\r\nmin. sel. est. : 0.00000050\r\n<span style=\"color: #ff0000;\"><strong>** Not using dynamic sampling for single table sel. or cardinality.<\/strong><\/span>\r\nDS Failed for : ----- Current SQL Statement for this session (sql_id=bzacaa129jp2q) -----<\/pre>\n<p>We sampled almost <strong>four percent<\/strong> of the original table (1023 blocks), but still no luck.<\/p>\n<blockquote>\n<p>Note that your results might vary, depending on the random blocks sampled &#8211; some levels below 10 might produce usable results, most however won&#8217;t.<\/p>\n<\/blockquote>\n<p>Clearly this looks like bad luck, even higher levels of Dynamic Sampling don&#8217;t generate a reasonable estimate, and other options like Extended Statistics won&#8217;t help either.<\/p>\n<h2>Indexes For Help<\/h2>\n<p>But wait, I&#8217;ve already mentioned in the previous parts of the series that sometimes Dynamic Sampling can take advantage of indexes. So let&#8217;s create such an index:<\/p>\n<pre>create index parcels_idx on parcels (delivery_status, pickup_date);<\/pre>\n<p>Since the index should allow arriving at a very precise cardinality estimate for rare values (less than <strong>2,500 occurrences<\/strong>, more on that later) even with a small sample size let&#8217;s repeat the experiment using level 4:<\/p>\n<pre>-------------------------------------------------------------------------------------------\r\n| Id\u00a0 | Operation\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | Name\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | Rows\u00a0 | Bytes | Cost (%CPU)| Time\u00a0\u00a0\u00a0\u00a0 |\r\n-------------------------------------------------------------------------------------------\r\n|\u00a0\u00a0 0 | SELECT STATEMENT\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 |\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 |\u00a0\u00a0\u00a0\u00a0 1 |\u00a0\u00a0 185 |\u00a0\u00a0\u00a0\u00a0 4\u00a0\u00a0 (0)| 00:00:01 |\r\n|\u00a0\u00a0 1 |\u00a0 TABLE ACCESS BY INDEX ROWID| PARCELS\u00a0\u00a0\u00a0\u00a0 |\u00a0\u00a0\u00a0\u00a0 1 |\u00a0\u00a0 185 |\u00a0\u00a0\u00a0\u00a0 4\u00a0\u00a0 (0)| 00:00:01 |\r\n|*\u00a0 2 |\u00a0\u00a0 INDEX RANGE SCAN\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | PARCELS_IDX |\u00a0\u00a0\u00a0\u00a0 <span style=\"color: #ff0000;\"><strong>1<\/strong><\/span> |\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 |\u00a0\u00a0\u00a0\u00a0 3\u00a0\u00a0 (0)| 00:00:01 |\r\n-------------------------------------------------------------------------------------------\r\n\r\nPredicate Information (identified by operation id):\r\n---------------------------------------------------\r\n\r\n   2 - access(\"PCL\".\"DELIVERY_STATUS\"='In-transit' AND \"PCL\".\"PICKUP_DATE\"&gt;=SYSDATE@!-1 AND \"PCL\".\"PICKUP_DATE\" IS NOT NULL)<\/pre>\n<p>Trace file snippet:<\/p>\n<pre>** Dynamic sampling initial checks returning TRUE (<span style=\"color: #ff0000;\"><strong>level = 4<\/strong><\/span>).\r\n\r\n*** 2012-05-29 18:50:05.158\r\n** Generated dynamic sampling query:\r\nquery text :\r\nSELECT \/* OPT_DYN_SAMP *\/ \/*+ ALL_ROWS IGNORE_WHERE_CLAUSE NO_PARALLEL(SAMPLESUB) opt_param('parallel_execution_enabled', 'false') NO_PARALLEL_INDEX(SAMPLESUB) NO_SQL_TUNE *\/ NVL(SUM(C1),0), NVL(SUM(C2),0), NVL(SUM(C3),0) FROM (SELECT \/*+ IGNORE_WHERE_CLAUSE NO_PARALLEL(\"PCL\") FULL(\"PCL\") NO_PARALLEL_INDEX(\"PCL\") *\/ 1 AS C1, CASE WHEN \"PCL\".\"DELIVERY_STATUS\"='In-transit' AND \"PCL\".\"PICKUP_DATE\"&gt;=SYSDATE@!-1 THEN 1 ELSE 0 END AS C2, CASE WHEN \"PCL\".\"PICKUP_DATE\"&gt;=SYSDATE@!-1 AND \"PCL\".\"DELIVERY_STATUS\"='In-transit' THEN 1 ELSE 0 END AS C3 FROM \"PARCELS\" SAMPLE BLOCK (0.116902 , 1) SEED (1) \"PCL\") SAMPLESUB\r\n\r\n*** 2012-05-29 18:50:05.173\r\n** Executed dynamic sampling query:\r\nlevel : 4\r\nsample pct. : 0.116902\r\n<span style=\"color: #ff0000;\"><strong>actual sample size : 912<\/strong><\/span>\r\n<span style=\"color: #ff0000;\"><strong>filtered sample card. : 0<\/strong><\/span>\r\n<span style=\"color: #ff0000;\"><strong>filtered sample card. (index PARCELS_IDX): 0<\/strong><\/span>\r\norig. card. : 1000000\r\nblock cnt. table stat. : 26518\r\nblock cnt. for sampling: 26518\r\nmax. sample block cnt. : 32\r\n<span style=\"color: #ff0000;\"><strong>sample block cnt. : 31<\/strong><\/span>\r\nmin. sel. est. : 0.00000050\r\n<span style=\"color: #ff0000;\"><strong>** Not using dynamic sampling for single table sel. or cardinality.<\/strong><\/span>\r\nDS Failed for : ----- Current SQL Statement for this session (sql_id=bzacaa129jp2q) -----<\/pre>\n<p>Unfortunately this doesn&#8217;t look much better: We can tell from the line <strong>&#8220;filtered sample card. (index PARCELS_IDX): 0&#8221;<\/strong> that the code recognized the index, but somehow it didn&#8217;t really use it.<\/p>\n<p>In the next part of this series we&#8217;ll see if the indexes can be of any help and what further options exist, if any.<\/p>\n<p>Go to <a title=\"Dynamic Sampling (II) \u2013 Controlling the Activity \u2013 Part 1\" href=\"https:\/\/allthingsoracle.com\/dynamic-sampling-ii-controlling-the-activity-part-1\/\" target=\"_blank\">Dynamic Sampling (II) &#8211; Controlling The Activity<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the previous parts of the series I outlined the basics on Dynamic Sampling. Let&#8217;s see how Dynamic Sampling deals with typical real-life data patterns. As you might be aware, quite often real data follows certain patterns for how data is clustered together, usually related to how the data arrives. This clustering (or scattering) of data within a table can&hellip;<\/p>\n","protected":false},"author":316197,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143533],"tags":[],"coauthors":[],"class_list":["post-73307","post","type-post","status-publish","format-standard","hentry","category-oracle-databases"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/73307","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/316197"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=73307"}],"version-history":[{"count":1,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/73307\/revisions"}],"predecessor-version":[{"id":91757,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/73307\/revisions\/91757"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=73307"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=73307"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=73307"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=73307"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}