Yes, as you've already discovered, a UNION query can run in parallel.
To fully understand what's going on here, you may want to read about parallel execution in the VLDB and Partitioning Guide.
Intra-operation parallelism can happen almost anywhere. Inter-operation parallelism only happens between producers and consumers. Which in this case means the UNION (a consumer) can execute in parallel the entire time. Each subquery (the producers) will execute in parallel, but not at the same time as each other.
You can see this happening in the example below, by looking at the active report for the query.
--Create two simple tables
create table test1(a number);
create table test2(a number);
--Populate them with 10 million rows
begin
for i in 1 .. 100 loop
insert into test1 select level from dual connect by level <= 100000;
insert into test2 select level from dual connect by level <= 100000;
end loop;
end;
/
commit;
--Gather stats
begin
dbms_stats.gather_table_stats(user, 'TEST1');
dbms_stats.gather_table_stats(user, 'TEST2');
end;
/
--Run a simple UNION.
select /*+ parallel */ count(*) from
(
select a from test1 join test2 using (a) where a <= 1000
union
select a from test2 join test1 using (a) where a <= 1000
);
--Find the SQL_ID by looking at v$sql, then get the active report
--(which must be saved and viewed in a browser)
select dbms_sqltune.report_sql_monitor(sql_id => 'bv5c18gyykntv', type => 'active')
from dual;
Here's part of the output. It's difficult to read, but it shows how the UNION, the first 11 steps of the plan, runs the whole time. The first subquery, the next 9 lines, runs during the first half of the query. Then the second subquery, the last 9 lines, runs during the second half of the query.
