Низкая производительность конвейерной функции в SQL Developer

У меня есть конвейерная табличная функция, например

FUNCTION FOO
(
    <PARAMETERS_LIST>
) RETURN T_TAB PIPELINED
AS
BEGIN
FOR rec IN
(<A LITTLE BIT COMPLEX QUERY WITH PARAMETERS_LIST>)
  LOOP
    PIPE row(T_WF(<COLUMN_LIST>));
  END LOOP;
  RETURN;
END FOO;

Я тестирую запрос в SQL Developer через select * from TABLE(FOO(<PARAMETERS_LIST>)) WHERE ROWNUM <= 200. Для возврата данных SQL Developer требуется 9 секунд.

Хотя при запуске <A LITTLE BIT COMPLEX QUERY WITH PARAMETERS_LIST> непосредственно в SQL Developer требуется 0,9 секунды.

Почему конвейерная функция такая медленная?


person comphilip    schedule 19.03.2015    source источник
comment
Сколько строк находит запрос — при обычном запросе требуется 0,9 секунды, чтобы вернуть все строки, или первую страницу результатов, или 200 строк? У вас есть ограничение rownum, когда вы запускаете его напрямую? Если это так, это может быть оптимизировано для количества стоп-ключей, но этого не произойдет в версии курсора, поскольку функция не знает, что вы ограничиваете результаты в этой точке. Показ плана выполнения для прямого запуска может что-то раскрыть; если вы ограничиваете это до 200 строк, покажите план выполнения и без этого ограничения.   -  person Alex Poole    schedule 19.03.2015
comment
Разработчик SQL показывает первые 50 строк простого запроса. Мы также добавляем rownum ‹= 50 к простому запросу и select * from TABLE(FOO(<PARAMETERS_LIST>)) WHERE ROWNUM <= 50, результат производительности тот же. Далее я проанализирую план выполнения.   -  person comphilip    schedule 20.03.2015


Ответы (1)


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

Что вы можете сделать, так это взглянуть на план, который оракул использует для выполнения вашего запроса:

explain plan for select * from TABLE(FOO(<PARAMETERS_LIST>)) WHERE ROWNUM <= 200

SELECT * 
FROM   TABLE(DBMS_XPLAN.DISPLAY);

это может дать вам ключ к пониманию того, где находится бутылочное горлышко.

Кстати, вы используете цикл в своей функции, это может вызвать переключение контекста, что определенно снизит производительность (намного). Постарайтесь предотвратить это, если сможете. Дополнительная информация о переключениях контекста: http://rajiboracle.blogspot.nl/2014/06/context-switches-and-performance-issue.html

person ErikL    schedule 19.03.2015
comment
Должно быть только два переключателя контекста — FOR r IN (qry) автоматически оптимизируется для выборки 100 строк за раз. - person Jeffrey Kemp; 19.03.2015
comment
Спасибо за ваше предложение. Мы проведем расследование в ближайшее время и дадим вам обратную связь. - person comphilip; 20.03.2015
comment
Это связано с отсутствием индексов. Переключение контекста здесь не проблема, поскольку требуется всего 200 записей. - person comphilip; 01.04.2015