Распараллелить вопросы запроса oracle union

У меня есть запрос Oralce, как это:

Sub_query1
Union
Sub_query2;

Я хочу распараллелить запрос. Я искал в Интернете и обнаружил, что UNION нельзя распараллелить, потому что подзапросы выполняются последовательно, а UNION не будет работать, пока не будут выполнены два подзапроса. И они говорят, что СОЮЗ можно распараллелить. Мой вопрос:

         (1) can a UNION query be parallezied? if yes, how? if no, why?
         (2) can I just parallelize the two sub queries?

Я использую Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64-разрядная версия

Спасибо!

3 ответа

Я думаю, что вы путаете выполнение двух запросов одновременно с параллельным выполнением запроса. SQL - это описательный язык, который переводится в код механизмом SQL / оптимизатором. Этот план запроса состоит из множества различных компонентов, предназначенных для извлечения данных из таблицы, выполнения объединения, агрегирования и т. Д.

Oracle создает план запроса для вашего запроса объединения. Каждый компонент плана запроса может использовать все доступные процессоры (при условии соблюдения правильных условий). Однако каждый компонент в основном запускается по одному (в разумном приближении). Таким образом, компоненты запроса распараллелены, хотя два подзапроса не выполняются одновременно.

Один совет. Всякий раз, когда вы думаете об использовании UNION, вы должны спросить себя, является ли UNION ALL также будет работать. UNION ALL гораздо эффективнее, потому что не нужно удалять дубликаты в конечном наборе результатов.

Да, как вы уже обнаружили, запрос UNION может выполняться параллельно.

Чтобы полностью понять, что здесь происходит, вы можете прочитать о параллельном выполнении в VLDB и Руководстве по разделам.

Внутриоперационный параллелизм может произойти практически где угодно. Межоперационный параллелизм происходит только между производителями и потребителями. Что в данном случае означает, что UNION (потребитель) может выполняться параллельно все время. Каждый подзапрос (производители) будет выполняться параллельно, но не одновременно друг с другом.

Вы можете увидеть это в примере ниже, посмотрев на активный отчет по запросу.

--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;

Вот часть вывода. Трудно читать, но это показывает, как UNION, первые 11 шагов плана, работает все время. Первый подзапрос, следующие 9 строк, выполняется в течение первой половины запроса. Затем второй подзапрос, последние 9 строк, выполняется во второй половине запроса.активный отчет для параллельного запроса UNION

Проведя несколько тестов и сравнив планы выполнения, я наконец нашел способ распараллелить объединение следующим образом:

select/* +parallel (Result) */ * from
(Sub_query1
Union
Sub_query2) Result;

При этом время и процессор обойдутся почти в половину от серийной версии. Добавление параллельных подсказок к обоим подзапросам не меняет время и стоимость процессора.

Другие вопросы по тегам