Я видел много постов об использовании курсоров в PL / SQL для возврата данных в вызывающее приложение, но ни один из них не затрагивал проблему, которая, как мне кажется, связана с этой техникой. Я довольно новичок в Oracle, но имею большой опыт работы с MS SQL Server. На сервере SQL при построении запросов, вызываемых приложением для возврата данных, я обычно помещаю инструкцию SELECT в хранимый pro c с / без параметров и позволяю сохраненному pro c выполнять оператор (ы). ) и вернуть данные автоматически. Я узнал, что с PL / SQL вы должны сохранить результирующий набор данных в курсоре, а затем использовать курсор.
У нас есть запрос, который не обязательно возвращает огромное количество строк (~ 5K - 10K строк), однако набор данных очень широкий, так как состоит из 1400+ столбцов. Выполнение запроса SQL в SQL Разработчик мгновенно возвращает результаты. Однако вызов процедуры, которая открывает курсор для того же запроса , занимает 5+ минут до завершения sh.
CREATE OR REPLACE PROCEDURE PROCNAME(RESULTS OUT SYS_REFCURSOR)
AS
BEGIN
OPEN RESULTS FOR
<SELECT_query_with_1400+_columns>
...
END;
После некоторой отладки, чтобы попытаться найти причину root медленности, я наклоняюсь к курсору, возвращающему одну строку за раз очень медленно. Я могу увидеть это в реальном времени, преобразовав pro c код в блок PL / SQL и используя DBMS_SQL.return_result(RESULTS)
после запроса SELECT. При запуске я вижу каждую строку в окне вывода Script в SQL Developer по одной. Если именно так курсор возвращает данные вызывающему приложению, то я определенно вижу, как это является узким местом, так как это может занять 5-10 минут, чтобы завершить sh, возвращая все строки 5K-10K. Если я удаляю столбцы из запроса SELECT, курсор отображает все строки намного быстрее, поэтому кажется, что большое количество столбцов является проблемой при использовании курсора.
Зная, что выполнение запроса SQL само по себе возвращает мгновенные результаты, как я могу получить эту же производительность из курсора? Не похоже, что это возможно. Ответ помещает встроенный SQL в код приложения и не использует процедуру / курсор для возврата данных в этом сценарии? Мы используем Oracle 12 c в нашей среде.
Редактировать: Просто хочу рассказать о том, как я тестирую производительность, используя обычный запрос SELECT против блока PL / SQL с помощью метода курсора:
SELECT (для возврата ~ 6K строк требуется ~ 27 секунд):
SELECT <1400+_columns>
FROM <table_name>;
PL / SQL с курсором (для возврата ~ 6K строк требуется ~ 5-10 минут):
DECLARE RESULTS SYS_REFCURSOR;
BEGIN
OPEN RESULTS FOR
SELECT <1400+_columns>
FROM <table_name>;
DBMS_SQL.return_result(RESULTS);
END;
В некоторых комментариях говорится о том, что происходит в консольном приложении после возврата всех данных, но я говорю только о производительности двух методов, описанных выше в Oracle \ SQL Developer. Надеюсь, это поможет прояснить то, что я пытаюсь донести.