oracle SQL查询耗时过长和超时

eanckbw9  于 2023-10-16  发布在  Oracle
关注(0)|答案(1)|浏览(237)

我有下面的SQL查询,需要大约2个小时的运行时间,并且经常失败,
ORA-08103:对象不再存在。
它查询的表有不到400万行。如果我只对几条记录尝试相同的查询,它工作正常(仍然需要很长时间,但没有错误)。请让我知道如何改变这一点,以运行更快,而不是错误了。

SELECT /*+ NO_STATEMENT_QUEUING PARALLEL(table64) ORDERED PQ_DISTRIBUTE(table1 BROADCAST, NONE) USE_HASH*/ 
         pt.proj_id,
         pt.wbs_id,
         pt.task_id,
         CASE WHEN rc.pm_budget_resource_code = 'LABOR' THEN COALESCE(rxl.new_org_code, cad.ca_cost_org_code)
              ELSE rc.pm_budget_resource_code
         END AS rsrc_short_name,
         cad.taskrsrc_id,
         SUM(cumulative_amt) expend_amt
FROM     table1 cad
INNER JOIN table2 rc ON (cad.etl_foa_code = rc.etl_foa_code
                                      AND cad.resource_code = rc.resource_code
                                      AND rc.pm_budget_resource_code != 'WKBOTHCOE')
INNER JOIN table3 wi ON (cad.etl_foa_code = wi.etl_foa_code
                                 AND cad.ca_wi_code = wi.wi_code)
INNER JOIN table4 pt ON (COALESCE(wi.task_id, wi.p2_conv_task_id) = pt.task_id)
LEFT OUTER JOIN (SELECT DISTINCT 
                        old_org_code, 
                        new_org_code 
                 FROM   table5) rxl ON (cad.ca_cost_org_code = rxl.old_org_code)
WHERE cad.cost_type != 'UFC'
AND   cad.cumulative_amt != 0
AND   cad.moa_code != 'R1'
AND   cad.resource_code NOT IN ('FLUX','CAPINT')
AND  (cad.cost_type != 'WIP' 
 OR  (cad.cost_type = 'WIP' 
AND  (cad.etl_foa_code, cad.fund_acct_no) NOT IN (SELECT farv.etl_foa_code,
                                                         farv.fund_acct_no
                                                  FROM   table6 vv,
                                                         table7 co,
                                                         table8 farv
                                                  WHERE  farv.fund_type_code = 'E'
                                                  AND    co.far_order_no = farv.far_order_no
                                                  --AND    vv.vendor_id = co.debtor_id
                                                  AND    vv.addr_id = co.debtor_id
                                                  AND    vv.debtor_class_code IN ('OC','ID'))))
GROUP BY pt.proj_id,
         pt.wbs_id,
         pt.task_id,
          CASE WHEN rc.pm_budget_resource_code = 'LABOR' THEN COALESCE(rxl.new_org_code, cad.ca_cost_org_code)
              ELSE rc.pm_budget_resource_code
         END,
         cad.taskrsrc_id
HAVING   SUM(cumulative_amt) != 0;
lokaqttq

lokaqttq1#

如果没有数据库的更多细节,很坚韧确定。但这里有一些一般性的指导,可能有助于照顾这一点:
1.索引:确保JOIN和WHERE条件中使用的列已被索引。这对于大table来说尤其重要。
1.子查询:WHERE子句中的子查询可能开销很大。如果它不经常改变的话,你可以考虑把它具体化。
1.提示:您已经使用了NO_STATEMENT_QUEUING和PARALLEL等提示。通过使用和不使用它们进行测试,确保它们确实提高了性能。
另外,您可以考虑使用NOT EXISTS而不是NOT IN来更改WHERE子句中的子查询。这应该更有效,并避免潜在的NULL问题。

相关问题