Parallel Execution Skew – 12c Hybrid Hash Distribution With Skew Detection

Since Parallel Execution Skew is a common problem that can severely limit the scalability of Parallel Execution (see my previous article for a demonstration), Oracle has introduced a new feature in 12c that can address the problem automatically. That’s great, but unfortunately – at least in the initial 12c release – it only applies to a limited number of scenarios,

Since Parallel Execution Skew is a common problem that can severely limit the scalability of Parallel Execution (see my previous article for a demonstration), Oracle has introduced a new feature in 12c that can address the problem automatically. That’s great, but unfortunately – at least in the initial 12c release – it only applies to a limited number of scenarios, so we still need to look at ways how to address the problem manually. Nevertheless it’s a great feature and a good starting point, maybe in future releases Parallel Execution Skew will be addressed automatically by the database in all the most common scenarios. Until that happens, we’ll have to resort to workarounds.

For the feature to be triggered automatically Oracle needs a histogram on the join expression. Oracle will use the histogram information to check for popular values – if the histogram shows that such popular values exist a special code path in the optimizer will be triggered that runs a recursive query on the table during optimization to generate a list of such popular values. These values will actually be hard-coded into the cursor information, and the HYBRID HASH distribution of “the other” row source at run time will check the data to distribute against this list of popular values in the cursor. If there is a match the value will be selectively distributed via BROADCAST to all receiving Parallel Execution Servers (all other values will still use the HASH distribution), and for the table with the skewed, popular values data that matches won’t be distributed via HASH, but simply in a random / round-robin fashion.

This way, any data having the popular values will be evenly distributed among the receiving Parallel Execution Servers, and due to the BROADCAST of the popular values in the other row source the join is still guaranteed to produce correct results, as the join will find a match no matter which worker process gets the values assigned.

Note: If you’re looking for more details how this feature works, see this accompanying post on my blog.

Let’s see that using our previous example. For the feature to be triggered we need to add a histogram on the corresponding column:

and re-execute the parallel variant of our query:

On my test system the query is back to 15 seconds, so that’s a great improvement compared to the 45 seconds it took without the new feature.

We can see the good distribution confirmed by looking at the output of V$PQ_TQSTAT again. By looking at the computed sub-totals we can also see confirmed that Oracle has actually selectively distributed the popular value for the “other” row source T_1, as indicated by 2000003 rows being produced / consumed rather than the actual 2000000 rows that the row source consists of – so the popular value “1” was broadcast to all four worker processes:

Here is the corresponding execution plan from 12c:

The new feature is indicated in operation ID = 12 by the keyword “(SKEW)” in the “PX SEND HYBRID HASH (SKEW)” operation. By the way, I believe that the “PQ Distrib” column is supposed to show the same “HYBRID HASH (SKEW)” distribution but is simply truncated in the output. According to my description above in my opinion the other PX SEND HYBRID HASH operation (the distribution of T_1) should also be flagged with “(SKEW)” because it doesn’t do a simple hash distribution, but does a mixed BROADCAST/HASH distribution.

But as pointed out before, the SKEW aware distribution feature at present does only work in certain scenarios. For example, if you make the join an outer join, or if you replace the full table scan on T_2 with a simple unmerged view, or make T_2 the build row source rather than then probe row source, then the feature isn’t triggered:

Outer Join example:

T_2 as build row source:

T_2 as simple view row source:

All these queries are back to 45 seconds on my test system and the execution plan doesn’t show any sight of the SKEW detection feature.

It’s also worth pointing out that the special SKEW aware distribution is only supported with hash joins, so, for example, using a parallel MERGE JOIN instead in the previous example won’t trigger the SKEW aware distribution either.

Furthermore if you happen to have joins to more than two tables then the join order dictates whether the feature might get used or not.

For example this three table join makes use of the feature:

But this one here uses slightly different joins and a different join order that joins T_2 first to another instance of T_1, so it doesn’t make use of the feature and therefore suffers again from skew:

So what can we do to address Parallel Execution Skew manually, in cases where in 12c the new skew aware distribution doesn’t work yet or in versions prior 12c? We’ll have a look at that in the next part of the series.