Автоматическая параллельная буферизация Oracle SQL

У меня есть тяжелый запрос, который буферизует данные в CSV-файл, который отправляется пользователям. Я вручную создал параллельные сеансы и выполняю запрос с условием фильтра, чтобы я мог объединить все буферные файлы в конце в один файл, тем самым сократив время на создание данных (обычно это занимает около 10 часов, с параллельными сеансами требуется 2,5-3 часа).

Мой вопрос заключается в том, как я могу автоматизировать это, чтобы скрипт узнал max (agreementid), а затем распределил его по X количеству вызовов спула для создания X файлов, где каждый файл будет иметь максимум 100000 записей, скажем.

Дополнительное объяснение: я думаю, мой вопрос был не очень ясен. Я попробую еще раз объяснить.

  1. У меня есть таблица/представление с большим объемом данных.
  2. Мне нужно спулировать эти данные в файл CSV.
  3. Для буферизации CSV-файла требуется огромное количество времени.
  4. Я запускаю параллельные катушки, делая ниже. а) Выберите .... из ..., где идентификатор соглашения находится в диапазоне от 1 до 1000000; б) Выберите .... из ..., где идентификатор соглашения находится в диапазоне от 1000001 до 2000000; и так далее, а затем буферизовать их по отдельности в несколько сеансов.
  5. Это помогает мне создать несколько файлов, которые я затем могу склеить и поделиться с пользователями.
  6. Мне нужен скрипт (думаю, на основе DOS или AIX), который будет находить минимальный и максимальный идентификатор соглашения из моей таблицы, автоматически создавать сценарии буферизации и выполнять их через отдельные сеансы SQL, чтобы я получал файлы, сгенерированные автоматически.

Не уверен, что смог бы достаточно ясно изложить свои мысли. Спасибо, ребята, за ответ на мой предыдущий запрос, но это было не то, на что я смотрел.


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


Ответы (2)


Немного неясно, что вы хотите, но я думаю, вы хотите, чтобы запрос находил низкий/высокий диапазон соглашений_id для 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);

А затем передайте каждый мин/макс скрипту SQL, например. из сценария оболочки, вызывающего SQL*Plus. Номер корзины также может быть передан и использоваться как часть имени файла спула через позиционный параметр.

Мне любопытно, что вы определили как узкое место; Вы пытались запустить его как параллельный запрос внутри базы данных с подсказкой /*+ PARALLEL */?

person Alex Poole    schedule 05.08.2013
comment
Спасибо, попробую оба варианта. - person user1859050; 14.08.2013