ORACLE中Update语句的性能调优

问题描述 投票:0回答:1

我有这段代码,45万行数据需要8到9个小时才能完成。这种情况下如何提高性能呢?

tab_a
有10M数据。

Declare

cursor cur_dup is
Select col_a,col_b,count(1) from tab_a group by col_a,col_b having count(1) > 1;
Begin
  for cur_dup_rec in cur_dup loop
     
    update tab_a
    set qty = 0
    where col_a = cur_dup_rec.col_a and col_b = cur_dup_rec.col_b
    and trunc(u_created_date) <> (Select max(trunc(u_created_date)) from tab_a 
                                   where col_a = cur_dup_rec.col_a and col_b = cur_dup_rec.col_b);
                                   
    update tab_a
       set (u_modified_date) = trunc(sysdate)
     where col_a = cur_dup_rec.col_a and col_b = cur_dup_rec.col_b;
     
     for cur_dup2_rec in (Select distinct item,customer,location,requested_date 
                            from tab_a 
                           where col_a = cur_dup_rec.col_a and col_b = cur_dup_rec.col_b) loop
                           
           update tab_a
            set (u_modified_date) = trunc(sysdate)
            where item = cur_dup2_rec.item and customer = cur_dup2_rec.customer and location = cur_dup2_rec.location
            and to_char(requested_date,'DD-MON-YYYY') = cur_dup2_rec.requested_date;
            
     end loop;
  
  end loop;
End;
sql oracle plsql
1个回答
0
投票

停止使用循环并使用单个 SQL 语句。

对于前两个

UPDATE
,您可以使用类似以下内容:

MERGE INTO tab_a dst
USING (
  SELECT COUNT(1) OVER (PARTITION BY col_a, colb) AS cnt,
         MAX(u_created_date) OVER (PARTITION BY col_a, colb) AS max_u_created_date
  FROM   tab_a
) src
ON (dst.ROWID = src.ROWID AND src.cnt > 1)
WHEN MATCHED THEN
  UPDATE
  SET u_modified_date = TRUNC(SYSDATE),
      qty             = CASE
                        WHEN TRUNC(dst.u_modified_date) = TRUNC(src.max_u_created_date)
                        THEN dst.qty
                        ELSE 0
                        END;

我不确定您想通过嵌套循环中的最后一个

UPDATE
实现什么目的,但您几乎肯定不想使用嵌套循环并希望将其转换为 SQL 语句。

© www.soinside.com 2019 - 2024. All rights reserved.