SQL查询有点慢

时间:2011-11-30 14:39:36

标签: sql oracle plsql

几个星期前我写了这个查询,它完成了工作,但速度并不快。我通常写前端JAVA所以SQL不是我的东西......你能看到这个脚本中有任何改进的地方可能会让它运行得更快....我很感激帮助。

FUNCTION rollup_like_item_history_data (
   p_tamcn        IN VARCHAR2,  
   p_nsn          IN VARCHAR2, 
   p_work_year    IN VARCHAR2,  
   p_work_type_id IN NUMBER
)
  RETURN sys_refcursor
IS
  stmt       VARCHAR2(4000);
  result_cur sys_refcursor;  
BEGIN

    OPEN result_cur FOR
    SELECT DISTINCT 
           jp.id,jp.line_header.mwslin AS mwslin,  
           jp.sor_code, 
           jp.workload_year, 
           jp.line_header.fiscal_year AS fiscal_year,
           nsns.sac, 
           tamcns.tamcn, 
           nsns.nsn,
           DECODE(jp.line_header.nsn_id, 
                 NULL, jp.line_header.nomenclature, 
                 nsns.nomenclature) AS nomenclature,
           jp.line_header.sup AS sup,
           jp.line_header.work_type_id AS work_type_id
      FROM schedules sch, 
           job_plans JP, 
           master_nsn nsns, 
           master_tamcn tamcns, 
           TABLE(tamcns.pgd_group_id) (+) ntab, 
           pgd_groups pgds
     WHERE (nsns.nsn = p_nsn OR p_nsn IS NULL) 
       AND (UPPER(tamcns.tamcn) LIKE UPPER(p_tamcn) OR p_tamcn IS NULL)
       AND (jp.line_header.work_type_id = p_work_type_id OR p_work_type_id IS NULL)
    -- AND p_work_year = ntab.fiscal_year(+)
       AND ntab.pgd_group_id = pgds.id(+) 
       AND jp.line_header.nsn_id = nsns.id(+) 
       AND nsns.tamcn_id = tamcns.id(+)
       AND (    
            (p_work_year IS NULL         
             AND jp.workload_year < TO_CHAR(ADD_MONTHS(CURRENT_DATE, -24), 'YYYY')                   
             AND jp.line_header.fiscal_year < TO_CHAR(ADD_MONTHS(CURRENT_DATE, -24), 'YYYY')     
           )     
           OR    
              (        
               p_work_year is not NULL        
            -- AND p_work_year = ntab.fiscal_year(+)                      
               AND jp.workload_year =  p_work_year                      
               AND jp.line_header.fiscal_year = p_work_year       
              )
           )
       AND JP.REVISION = (select MAX(jp2.revision) 
                            from job_plans jp2
                           WHERE JP.CONTROL_NUMBER = JP2.CONTROL_NUMBER)
       AND  job_plan_pkg.get_last_job_plan_state_type(jp.id) != 1; 

3 个答案:

答案 0 :(得分:1)

  • 看看你是否可以删除WHERE子句中索引列上的任何UPPER()
  • 考虑用DENSE_RANK()= 1(example
  • 替换最后的SELECT MAX()

答案 1 :(得分:0)

这部分

AND JP.REVISION = (select MAX(jp2.revision) 
                            from job_plans jp2
                           WHERE JP.CONTROL_NUMBER = JP2.CONTROL_NUMBER)

将评估每条记录,使用内部联接而不是:

join (select control_number, max(revision) 
      from job_plans
      group by control_number) jp2
on jp.control_number = jp2.control_number 

此外,您可以在SQL Developer中查看并创建执行计划,也可以查看索引的使用情况,也许您的查询在低选择性的查询中使用全表扫描。

答案 2 :(得分:0)

当我把“schedule sch”从FROM条款中拿走时......快得多了......我忘了我删除了那个

的引用

让你们感到惊讶的是,SQL家伙并没有注意到......:)