Oracle SQL паралелно спулиране автоматично

Имам тежка заявка, която изпраща данни в csv файл, който се изпраща на потребителите. Направих ръчно паралелни сесии и изпълнявам заявката с условие за филтър, така че да мога да обединя всички споулирани файлове накрая в един файл, като по този начин намалявам времето за генериране на данните (обикновено отнема около 10 часа, с паралелни сесии отнема 2,5-3 часа).

Моето запитване е как мога да автоматизирам това, така че скриптът да открие max(agreementid) и след това да го разпредели в X брой извиквания на макарата, за да генерира X файлове, където всеки файл ще има максимум 100 000 записа.

Допълнително обяснение: Предполагам, че въпросът ми не беше много ясен. Ще се опитам да обясня отново.

  1. Имам таблица/изглед с голямо количество данни.
  2. Трябва да спулирам тези данни в CSV файл.
  3. Отнема огромно количество време за изпращане на CSV файл.
  4. Пускам успоредни макари, като правя по-долу. a) Изберете .... от ... където споразумението е между 1 до 1 000 000; b) Изберете .... от ... където споразумението е между 1000001 до 2000000; и така нататък и след това ги спулирайте поотделно в множество сесии.
  5. Това ми помага да генерирам множество файлове, които след това мога да съединя и споделя с потребителите.
  6. Имам нужда от скрипт (предполагам, че базиран на dos или базиран на AIX), който ще намери мин. и макс. на agreementID от моята таблица и ще създаде автоматично спулиращите скриптове и ще ги изпълни чрез отделни сесии на sql, така че да получа файловете, генерирани автоматично.

Не съм сигурен дали мога да се изразя достатъчно ясно. Благодаря, момчета, че отговорихте на предишното ми запитване, но не това гледах.


person user1859050    schedule 05.08.2013    source източник


Отговори (2)


Малко неясно какво искате, но мисля, че искате заявка за намиране на нисък/висок диапазон от agreement_ids за x групи идентификатори (кофи). Ако е така, опитайте нещо подобно (като използвате 4 кофи в този пример):

select bucket, min(agreement_id), max(agreement_id), count(1)
from (
  select agreement_id, ntile(4) over (order by agreement_id) bucket
  from my_table
)
group by bucket;

Редактиране: Ако проблемът ви е да се забърквате със спулиране на множество заявки и комбиниране, бих предпочел да избера създаване на един материализиран изглед (използване на паралел в основната заявка на управляващата таблица) и опресняване (пълно, atomic_refresh=>false), когато е необходимо. Веднъж опреснени, просто извлечете от таблицата с моментни снимки (в csv или какъвто формат искате).

person tbone    schedule 05.08.2013

Може да има по-прост начин, но това генерира четири „кофи“ с идентификатори и можете да включите минималните и максималните стойности във вашето параметризирано филтърно условие:

select bucket, min(agreementid) as min_id, max(agreementid) as max_id
from (
    select agreementid,
        case when rn between 1 and cn / 4 then 1
            when rn between (cn / 4) - 1 and 2 * (cn / 4) then 2
            when rn between (2 * cn / 4) - 1 and 3 * (cn / 4) then 3
            when rn between (3 * cn / 4) - 1 and cn then 4
        end as bucket
    from (
        select agreementid, rank() over (order by agreementid) as rn,
            count(*) over () as cn from agreements
    )
)
group by bucket;

Ако искате горна граница за всяка кофа, а не фиксиран брой кофи, можете да направите:

select floor(rn / 100000), min(agreementid) as min_id, max(service_num) as max_id
from (
    select agreementid, rank() over (order by agreementid) as rn
    from agreements
)
group by floor(rn / 100000);

И след това предайте всеки min/max на SQL скрипт, напр. от шел скрипт, извикващ SQL*Plus. Номерът на кофата също може да бъде предаден и да се използва като част от името на файла на буфера чрез позиционен параметър.

Любопитно ми е обаче какво сте идентифицирали като пречка; опитвали ли сте да го стартирате като паралелна заявка в базата данни, с подсказка /*+ PARALLEL */?

person Alex Poole    schedule 05.08.2013
comment
Благодаря, ще пробвам и двата подхода. - person user1859050; 14.08.2013