优化查询运行时间太长

时间:2009-09-17 11:18:12

标签: sql oracle optimization plsql

我使用toad for 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 个答案:

答案 0 :(得分:5)

查询性能不佳的常见原因是Oracle无法找到合适的索引。将EXPLAIN PLAN与TOAD一起使用,以便Oracle可以告诉您它认为执行查询的最佳方式。这应该会让你知道何时使用索引,何时不使用。

有关一般指示,请参阅http://www.orafaq.com/wiki/Oracle_database_Performance_Tuning_FAQ

请参阅here了解EXPLAIN PLAN。

答案 1 :(得分:3)

您的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。

答案 2 :(得分:0)

我已经用文字常量替换了函数调用,这只会加速一秒或2秒。查询仍然需要大约50秒才能运行。

我可以在连接周围做些什么来帮助实现这一目标。在这里正确使用了INNER JOIN功能。

我不确定我明白你对下面的意思或如何使用它。 当我尝试在第二个选择中调用该函数时,我得到错误d无效的标识符 select / * + no_merge(v)* / a,b,c,myfunction(d) 从    (选择a,b,c,d      来自my_table      哪里......    )v;

非常感谢任何其他观点

答案 3 :(得分:0)

在我们说任何明智的事情之前,我们必须先看看时间花在哪里。这意味着你必须先收集一些信息。

因此,我对这样一个问题的标准反应是:http://forums.oracle.com/forums/thread.jspa?threadID=501834

此致 罗布。