Получать данные из памяти вместо таблицы
У меня есть таблица параметров с 10 строками. Вызывается параметрическая таблица. В моей процедуре PL/SQL я делаю цикл в 2 миллиона записей. И каждый раз запрашивая эту таблицу параметров тоже.
Я хочу загрузить эту таблицу параметров в память и уменьшить процесс ввода-вывода.
Каков наилучший способ сделать это?
FOR cur_opt
IN (SELECT customer_ID,
NVL (customer_type, 'C') cus_type
FROM invoice_codes
WHERE ms.invoice_type='RT')
LOOP
....
...
Select data From parameter_table Where cus_type = cur_opt.cus_type AND cr_date < sysdate ; -- Where clause is much complex than this..
....
...
END LOOP;
3 ответа
Вы можете просто присоединить его к своему основному запросу:
select customer_id, data
from parameter_table t, invoice_codes c
where t.cus_type = nvl(c.customer_type, 'C')
and t.cr_date < sysdate
Однако, если у вас есть 2 миллиона записей в invoice_codes
затем присоединение к таблице параметров - это наименьшая из ваших проблем - циклическое выполнение этого займет некоторое время (и, вероятно, является реальной причиной ваших проблем ввода-вывода).
Я думаю, что вы можете изменить запрос, присоединившись к параметру-таблице, так что вам не нужно будет нажимать оператор выбора внутри цикла. (например, какое решение @Chris Saxon)
Но в качестве способа использования кэшированных данных вы можете заполнить словарь, например, массив, а затем ссылаться на него при необходимости.
Нечто подобное может помочь:
ты должен позвонить Fill_parameters_cash
перед началом основного процесса и вызова get_parameter
чтобы получить данные, входной параметр для вызова get_parameter
это словарь ключ
TYPE ga_parameter_t IS TABLE OF parameter_table%ROWTYPE INDEX BY BINARY_INTEGER;
ga_parameter ga_parameter_t;
procedure Fill_parameters_cash is
begin
ga_parameter.DELETE;
SELECT * BULK COLLECT
INTO ga_parameter
FROM parameter_table;
end Fill_parameters_cash;
FUNCTION get_parameter(cus_type invoice_codes.cus_type%TYPE,
is_fdound OUT BOOLEAN)
RETURN parameter_table%ROWTYPE IS
result_value parameter_table%ROWTYPE;
pos NUMBER;
BEGIN
result_value := NULL;
is_fdound := FALSE;
IF cus_type IS NULL THEN
RETURN NULL;
END IF;
pos := ga_parameter.FIRST;
WHILE pos IS NOT NULL
LOOP
EXIT WHEN ga_parameter(pos).cus_type = cus_type;
pos := ga_parameter.NEXT(pos);
END LOOP;
IF pos IS NOT NULL THEN
is_fdound := TRUE;
result_value := ga_parameter(pos);
END IF;
RETURN result_value;
END get_parameter;
Я предполагаю, что просмотр миллионов записей уже вызывает проблемы. Не совсем уверен, как этот поиск таблицы параметров действительно ухудшает его.
В любом случае, если это действительно единственный подход, который вы можете использовать, тогда вы можете выполнить внутреннее или внешнее соединение в объявлении курсора.
----
FOR cur_opt
IN (SELECT customer_ID,
NVL (customer_type, 'C') cus_type
FROM invoice_codes codes,
parameter_table par
WHERE ms.invoice_type='RT'
and codes.cus_type = par.cus_type -- (or an outer join) maybe?
) loop
..........