【问题标题】:Stored procedure for Select and Inner select query in OracleOracle 中 Select 和 Inner select 查询的存储过程
【发布时间】:2018-01-28 01:23:22
【问题描述】:

我有一个这样的查询:

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 数据库中运行此查询时,由于大量记录,此查询花费了太多时间。

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

【问题讨论】:

  • 为什么你认为一个程序会更快?查看执行计划,看看哪里慢。我想你的隐式日期转换和比较为字符串根本没有帮助。不过,使用not in 也会降低性能。您是否考虑过使用分析函数?
  • 我正在使用两个 select 语句,因此正在考虑编写一个 proc,其中内部 select 语句可以将数据放入某个临时表中,然后从该临时表中我可以运行外部 select 语句。通过这种方式,我可以删除 not in 调用。如果您能帮助我编写这样的过程,那将是非常有帮助的。

标签: oracle performance stored-procedures oracle11g


【解决方案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。

还有其他可能的性能改进,具体取决于通常的调优 考虑因素:数据量和偏差、索引等

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多