Оптимизировать запрос, который занимает слишком много времени для запуска - PullRequest
0 голосов
/ 17 сентября 2009

Im Использование toad для Oracle для запуска запроса, выполнение которого занимает слишком много времени, иногда более 15 минут.

Запрос извлекает напоминания, которые должны быть утверждены менеджерами. Запрос не возвращает много строк. Обычно, когда он запускается, он возвращает около 30 или 40 строк. Запрос должен получить доступ к нескольким таблицам для получения информации, поэтому я использую множество соединений для получения этой информации.

Я приложил свой запрос ниже. Если кто-то может помочь с оптимизацией этого запроса, я был бы очень рад.

Запрос:

SELECT (e.error_Description || DECODE(t.trans_Comment, 'N', '', '','', ' - ' || t.trans_Comment)) AS Title,
       t.Date_Time_Recorded AS Date_Recorded,
       DECODE(t.user_ID,0,'System',(SELECT Full_Name FROM employee WHERE t.user_Id = user_id)) AS Recorded_by,
           DECODE(t.user_ID,0, Dm_General.getCalendarShiftName(t.Date_Time_Recorded), (SELECT shift FROM employee WHERE t.user_Id = user_id)) AS Shift,
          l.Lot_Number AS entity_number,
          ms.Line_Num,
          'L' AS Entity_Type, 
           t.entity_id, l.lot_Id AS Lot_Id
      FROM DAT_TRANSACTION t
      JOIN ADM_ERRORCODES e ON e.error_id = t.error_id
      JOIN ADM_ACTIONS a ON a.action_id = t.action_id,
           DAT_LOT l
                 INNER JOIN Status s ON l.Lot_Status_ID = s.Status_ID,
          DAT_MASTER ms
                INNER JOIN ADM_LINE LN ON ms.Line_Num = LN.Line_Num
      WHERE
             (e.memo_req = 'Y' OR a.memo_req = 'Y')
          AND ms.Run_type_Id = Constants.Runtype_Production_Run --Production Run type
           AND s.completed_type NOT IN ('D', 'C', 'R') -- Destroyed /closed / Released
          AND LN.GEN = '2GT'
           AND (NOT EXISTS (SELECT 1 FROM LNK_MEMO_TRANS lnk, DAT_MEMO m
                           WHERE lnk.Trans_ID = t.trans_id AND lnk.Memo_ID = m.Memo_ID
                           AND NVL(m.approve, 'Y') = 'Y'))--If it's null, it's 
                                                  been created and is awaiting approval
          AND l.Master_ID = ms.Master_ID
           AND t.Entity_ID = l.Lot_ID
           AND t.Entity_Type IN ('L', 'G');

Ответы [ 4 ]

5 голосов
/ 17 сентября 2009

Обычной причиной плохой производительности запросов является то, что Oracle не может найти подходящий индекс. Используйте EXPLAIN PLAN с TOAD, чтобы Oracle мог сказать вам, что он считает наилучшим способом выполнения запроса. Это должно дать вам некоторое представление о том, когда он использует индексы, а когда нет.

Общие указатели см. http://www.orafaq.com/wiki/Oracle_database_Performance_Tuning_FAQ

См. здесь для ОБЪЯСНЕНИЯ ПЛАНА.

3 голосов
/ 17 сентября 2009

В вашем SQL есть несколько вызовов функций:

  • dm_general.getcalendarshiftname (t.date_time_recorded)
  • constants.runtype_production_run

Вызовы функций в SQL медленны и в зависимости от плана запроса могут вызываться избыточно много раз - например, вычисление dm_general.getcalendarshiftname для строк, которые в конечном итоге отфильтровываются из результатов.

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

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

select /*+ no_merge(v) */ a, b, c, myfunction(d)
from
   ( select a, b, c, d
     from my_table 
     where ...
   ) v;

Это гарантирует, что myfunction вызывается только для строк, которые появятся в результатах.

0 голосов
/ 17 сентября 2009

Прежде чем мы сможем сказать что-нибудь разумное, мы должны взглянуть на то, где тратится время. А это значит, что сначала вам нужно собрать некоторую информацию.

Поэтому моя стандартная реакция на такой вопрос: http://forums.oracle.com/forums/thread.jspa?threadID=501834

С уважением, Роб.

0 голосов
/ 17 сентября 2009

Я заменил вызовы функций на буквальные константы, и это ускоряет его всего на секунду или 2. Запрос все еще занимает около 50 секунд для выполнения.

Есть ли что-нибудь, что я могу сделать с Джоинсом, чтобы помочь мне? Используйте правильную функцию INNER JOIN здесь.

Я не совсем уверен, что понимаю, что вы имеете в виду относительно ниже или как это использовать. Я получаю ошибку d неверный идентификатор, когда я пытаюсь вызвать функцию во втором выборе выберите / * + no_merge (v) * / a, b, c, myfunction (d) от (выберите a, b, c, d из my_table где ... ) v;

Любые другие мнения будут с благодарностью

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...