2017-01-25 8 views
2

Это моя проблема:Почему время выполнения хранимой процедуры оракула значительно увеличивается в зависимости от того, как оно выполняется?

  • Мы хранимая процедура называется: HEAVY_SP excuted с теми же параметрами во всех сценариях
  • У нас есть разработчик Oracle SQL. Это можно назвать: IDE

В зависимости от того, как он выполняется, время выполнения значительно увеличивается:

  • (1)CALL HEAVY_SP(0, 'F', 5, ...) непосредственно в окне запроса (IDE) = 15 секунд (Наше текущее решение)

  • (2) Использование специальная кнопка IDE = 15 секунд

  • (3) Использование DBMS_JOB (запланированное выполнение) = 15 секунд

Работа планируется и не выполняется.Работа выполняется с помощью IDE (правой кнопки мыши и выполнить)

  • (4) Использования DBMS_JOB (Instant Execution) = более 01 часов, итерацию очень медленно

  • (5) Из SQL_PLUS (Linux) = более чем 01 часов, итерация очень медленно

  • (6) С JAVA = более 01 часов, итерация очень медленно

  • (7) От TOAD = более 01 часов, итерация очень медленно

У нас есть съедено много страниц Google, таких как:

why-does-a-query-run-slower-in-a-stored-procedure-than-in-the-query-window

oracle-pl-sql-procedure-runs-slower-than-sql

oracle-insert-in-stored-procedure-very-slow-compared-to-insert-run-manually

stored-proc-running-30-slower-through-java-versus-running-directly-on-database

Так что мой вопрос, являются:

  • Почему Oracle действовать таким образом?
  • Не должно ли оно вести себя быстро во всех сценариях (одинаковые параметры)?
  • Сохраненная процедура должна быть изменена?
  • Если план запроса, файлы трассировки или статистические данные показывают отклонения от поведения, необходимо сохранить сохраненную продекурацию?
  • Почему выполнение в окне запроса происходит быстро?

Заранее спасибо.

[EDIT]

Следуя рекомендациям @BobJarvis о статистике

Наша статистика в актуальном состоянии. Даже, мы выполнили EXEC DBMS_STATS.GATHER_TABLE_STATS(ownname=>'SOME_USER', tabname=>'SOME_TABLE', cascade => TRUE); во всех таблицах проблем и результат тот же.

[EDIT]

Следуя рекомендациям @KonstantinSorokin

Я подозреваю, что планы выполнения могут отличаться из-за разницы в настройках сессий. Рассмотрим сравнение v$ses_optimizer_env

Мы исследовали и результат: параметры одинаковы для (1) и (4) сценарии.

[EDIT]

Используя этот запрос:

select s.sid,s.serial#,s.username, s.machine,replace(q.SQL_FULLTEXT,chr(0)) sql_text, s.program, s.logon_time, s.status, s.OSUSER 
from v$session s, v$sql q 
where 
s.status='ACTIVE' 
and s.username is not null 
and s.sql_hash_value = q.hash_value 
order by s.LOGON_TIME, s.username; 

Я заметил, что изменение машины, программы и ouser в зависимости от теста:

БЫСТРОГО MODE (окно запроса)

machine    | program   | ouser 
--------------------|------------------ | ------- 
my laptop username | SQL DEVELOPER  | User 

LAG MODE (исполнение фона)

machine    | program   | ouser 
--------------------|------------------ | ------- 
ip-10-6-7-1   | [email protected]| rdsdb 

[EDIT]

Следуя рекомендациям @KonstantinSorokin связанных с трассам.

Временный администратор базы данных исследовал, и Он сказал нам, что у некоторых sql_id есть разные планы выполнения. Его совет: использовать подсказки.

Это может быть решение, но почему у некоторых идентификаторов SQL есть разные планы выполнения?

[РЕШИТЬ]

Благодаря @IsaacMejia, NLS_COMP = лингвистический была причина медленно исполнения. Решение должно быть установлено NLS_COMP = BINARY на уровне экземпляра, но во избежание проблем с упорядочением и сопоставлениями в приложении, которые используют эту базу данных, я не могу переопределить параметры NLS экземпляра.

Временное решение выполнить в начале хранимой процедуры:

execute immediate 'alter session set NLS_COMP=''BINARY'''; 

и вернуться к предыдущему значению на финише:

execute immediate 'alter session set NLS_COMP=''LINGUISTIC'''; 

Теперь хранимая процедура запуска быстро, как непосредственно выполнение в окне запроса (ORACLE SQL DEVELOPER)

+1

Были ли параметры одинаковыми для всех различных вызовов, как быстрых, так и медленных, или были разные параметры? Как давно были проанализированы все таблицы, используемые (прямо или косвенно) с помощью хранимой процедуры? Какие параметры были предоставлены для 'DBMS_STATS.GATHER_TABLE_STATISTICS' для каждой из таблиц? –

+1

Я предполагаю, что есть неявное преобразование типа где-то, что зависит от определенного для сеанса параметра, такого как NLS_DATE_FORMAT. Например, если код выглядит как '... и date_column = '01/01/2000'', он может работать по-разному в зависимости от настроек клиента по умолчанию. Можете ли вы поделиться кодом? –

+0

Я не уверен, что понимаю «Never Ends, Iteration Slow». Если итерация медленная, то она должна закончиться в какое-то время? Что делает хранимая процедура? Выдает ли он один или несколько операторов SQL? Если да, можете ли вы поделиться ими вместе с планом исполнения? Если это более одного, можете ли вы сузить его до одного оскорбительного заявления? – BobC

ответ

2

Попробуйте получить параметры nls из ваших разных случаев (программы ide или java), они должны быть разными

select * from NLS_SESSION_PARAMETERS 

Затем в вашей процедуре магазина задайте переменные, чтобы сделать их равными из самого быстрого.

execute immediate 'alter session set NLS_SORT=''SPANISH'''; 

Как только у вас SP есть все параметры nls. Он будет работать быстро.

Я недавно нашел аналогичный случай в Alter session slows down the query through Hibernate. но в их случае они меняют параметры, а затем становятся медленными.

я исследовал и обнаружил, что параметры NLS_COMP у NLS_SORT может повлиять как оракул сделать использование выполнить план строки (когда он сравнивает или заказ)

Когда NLS_COMP определяется как лингвистический он будет использовать язык определения в NLS_SORT.

, например, если NLS_COMP = лингвистический и NLS_SORT = BINARI_AI ваши querys является

select * from table where string_column like 'HI%' 

внутренне он будет делать

select * from table where 
NLSSORT(string_column,'BINARI_AI') >= HEXTORAW('324242432') 
NLSSORT(string_column,'BINARI_AI') >= HEXTORAW('675757576') 

так, если вы не имеете индекс для NLSSORT (колонка» BINARI_AI '), это будет очень медленно.

зная, что NLS_SORT = BINARY_AI сделает акцентирование без учета регистра и без учета регистраций вашего заказа и сравнений.

+0

Спасибо @IsaacMejia. Я попробую. – JRichardsz

+0

Привет @IsaacMejia, вы правы. NLS_COMP = LINGUISTIC была причиной медленного выполнения. После установки значения BINARY хранимая процедура выполняется быстро, как прямое выполнение в окне запроса (ORACLE SQL DEVELOPER). БОЛЬШОЕ СПАСИБО!! – JRichardsz