PLSQL 块需要很长时间来声明游标

Posted

技术标签:

【中文标题】PLSQL 块需要很长时间来声明游标【英文标题】:PLSQL block takes very long time to declare a cursor 【发布时间】:2012-11-06 12:55:55 【问题描述】:

我正在执行一个 PL/SQL 块,它从显式游标更新一些行。声明游标的代码如下:

cursor DUP_SUBJECTS is  
  select * 
    from ODS_SUBJECT_D  
   WHERE SUBJECT_COD = ANY (SELECT SUBJECT_COD  
                              FROM ODS_SUBJECT_D  
                             WHERE END_DATE = TO_DATE ('31-12-9999','DD-MM-YYYY')   
                             GROUP BY SUBJECT_COD, ROW_TYPE_DE  
                            HAVING COUNT(*) > 1)  
   ORDER BY SUBJECT_COD, START_DATE; 

正文中的第一条语句是DBMS_OUTPUT.PUT_LINE,用于通知它何时开始执行该块。上述脚本中的查询返回表中 2900000 行中的 20000 行。在脚本的声明块中似乎需要很长时间(30 分钟后它还没有打印消息)。 有什么建议可以优化脚本的性能吗?

谢谢, 安东尼奥

【问题讨论】:

【参考方案1】:

您误解了DBMS_OUTPUT 的工作原理。在您的代码块完整运行之前,客户端无法接收发送到DBMS_OUTPUT 的消息。您可以通过在DBMS_OUTPUT 消息中添加时间戳来验证这一点。我怀疑您会看到第一条消息几乎是立即写入的,而实际的瓶颈在其他地方。

【讨论】:

【参考方案2】:

您可以尝试不同的查询方式:

cursor dup_subjects is  
  select
    * 
  from (
    select
      o.*,
      count(*) over (partition by subject_cod, row_type_de) count_per
    from
      ods_subject_d
    where
      end_date = date '9999-12-31')
  where
    count_per > 1
  order by
    subject_cod,
    start_date;

如果 end_date 不是一个非常常见的值,请确保它被索引 - 如果您不经常查询 end_date 除了这个值,那么考虑索引:

create index ...
on     ods_subject_d (
         case end_date
           when date '9999-12-31' then 1
         end)

... 并将谓词更改为 ...

where case end_date when date '9999-12-31' then 1 end = 1

如果对值的分布和满足“count(*) > 1”条件的可能性有更多了解,可能会进一步细化索引和查询。

【讨论】:

【参考方案3】:

如果您的 pl/sql 块运行时间较长并且没有退出程序, 那么你需要在适当的列上创建索引。

【讨论】:

以上是关于PLSQL 块需要很长时间来声明游标的主要内容,如果未能解决你的问题,请参考以下文章

Android MediaPlayer 需要很长时间来准备和缓冲

结果集需要很长时间来处理来自 Oracle 的大数据

简单的 MySQL 查询需要很长时间来计算

避免花很长时间来完成“牛奶过多”的场景

包“apppxbundle”需要很长时间来处理。无法将更新推送到 Windows 商店 [UWP] [Xamarin.Forms]

为什么phpMyAdmin需要很长时间来显示查询,但是显示查询执行得很快? [关闭]