Oracle中Select和Inner select查询的存储过程

时间:2017-08-19 13:35:49

标签: oracle performance stored-procedures oracle11g

我有这样的查询:

select PROMOTER_DSMID, 
      PROMOTER_NAME, 
      PROMOTER_MSISDN, 
      RETAILER_DSMID,
      RETAILER_MSISDN, 
      RETAILER_NAME ,
      ATTENDANCE_FLAG,
      ATTENDANCE_DATE 
from PROMO_ATTENDANCE_DETAILS
where PROMOTER_DSMID not in 
       (SELECT PROMOTER_DSMID
        FROM PROMO_ATTENDANCE_DETAILS 
        WHERE PROMOTERS_ASM_DSMID='ASM123'
        AND ATTENDANCE_FLAG='TRUE' 
        AND TRUNC(ATTENDANCE_DATE) ='16-07-17') 
   and   PROMOTERS_ASM_DSMID='ASM123'
  AND ATTENDANCE_FLAG='FALSE' 
  AND TRUNC(ATTENDANCE_DATE) ='16-07-17';

由于存在大量记录,因此在PROD数据库中运行此查询时会花费太多时间。

我需要为此编写一个过程,但是无法获得如何编写过程的正确方法。有人请指导我。

1 个答案:

答案 0 :(得分:1)

  

"正在考虑编写一个proc,其中内部select语句可以将数据放入某个临时表中,然后从该临时表中我可以运行外部select语句"

没必要。使用WITH子句选择一次数据并使用两次。

with cte as (    
    select PROMOTER_DSMID, 
          PROMOTER_NAME, 
          PROMOTER_MSISDN, 
          RETAILER_DSMID,
          RETAILER_MSISDN, 
          RETAILER_NAME ,
          ATTENDANCE_FLAG,
          ATTENDANCE_DATE 
    from PROMO_ATTENDANCE_DETAILS
    where  PROMOTERS_ASM_DSMID='ASM123'
    AND TRUNC(ATTENDANCE_DATE) ='16-07-17'
)
select * 
from cte
where ATTENDANCE_FLAG='FALSE' 
AND PROMOTER_DSMID not in 
   (SELECT PROMOTER_DSMID
    FROM cte
    where ATTENDANCE_FLAG='TRUE') 
;

这将比临时表执行得更好,后者涉及大量磁盘I / O.

根据通常的调整,还有其他可能的性能改进 注意事项:数据量和偏斜,索引等