конвейерная функция - PullRequest
       6

конвейерная функция

0 голосов
/ 11 марта 2010

Может кто-нибудь привести пример использования функции параллельных таблиц в oracle pl / sql. Нам нужно выполнить массивные запросы в течение 15 лет и объединить результат.

SELECT * 
  FROM Table(TableFunction(cursor(SELECT * FROM year_table))) 

... это то, что мы хотим эффективно. Самый внутренний выбор даст все годы, а табличная функция будет брать каждый год, выполнять массивный запрос и возвращать коллекцию. Проблема, с которой мы столкнулись, состоит в том, что все годы используются для одной табличной функции, и мы бы предпочли, чтобы табличная функция вызывалась параллельно для каждого года. Мы пробовали все виды разбиения по хэшам и диапазонам, и это не помогло.

Кроме того, можем ли мы удалить ключевое слово PIPELINED из объявления функции? потому что мы не выполняем никаких преобразований и просто нуждаемся в совокупности набора результатов.

1 Ответ

2 голосов
/ 12 марта 2010

Здесь отличная рецензия здесь .

Существуют альтернативные подходы (например, «основное» задание, которое курсирует через YEAR_TABLE и отправляет DBMS_JOB для обработки каждый год. Каждое «годовое задание» вставляет свои результаты в таблицу.

Как только все созданные задания завершены, вы просто извлекаете результаты из таблицы.

PS. Я подозреваю, что параллельный конвейер не будет делать то, что вы хотите, хотя. Я создал большую таблицу из трех строк с определенным значением. Затем я создал параллельную конвейерную функцию, которая просто выдавала SID исполняемого процесса (см. Ниже) и количество строк, которые он обрабатывает. У меня был SQL, который выбрал эти три строки и передал их как курсор в функцию. В основном функция выдвинула два разных идентификатора безопасности (именно это EXPLAIN PLAN сказал мне, что выбрано в качестве степени параллелизма). Иногда показывалось, что два процесса были выполнены, но все три строки были обработаны одним из этих процессов.

Таким образом, дело не в том, что строки будут выбраны из курсора и переданы для обработки параллельным ведомым, а каждому параллельному процессу будет предоставлен фрагмент таблицы управления для обработки. С небольшой таблицей, она, вероятно, не будет рассматривать параллель, и даже если это так, она может просто выделить первые 50 строк первому процессу и т. Д.

CREATE OR REPLACE FUNCTION test_pp(p_source     IN SYS_REFCURSOR)
   RETURN TAB_CHAR_4000  PIPELINED
   PARALLEL_ENABLE (PARTITION p_source BY ANY)
IS
   v_num NUMBER;
BEGIN
   FETCH p_source INTO v_num;
   WHILE p_source%FOUND LOOP
            PIPE ROW(sys_context('USERENV','SID'));
            FETCH p_source INTO v_num;
   END LOOP;
     PIPE ROW(sys_context('USERENV','SID')||':'||p_source%ROWCOUNT);
   CLOSE p_source;
   RETURN;
END test_pp;
/
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...