update update multi-table summary

General principles: 1) The where condition must be added when updating, otherwise it will inevitably cause all records in the field to be updated

                   2) When updating across tables, when set and where, try to reduce the number of scans to improve optimization

 

update update instance:

 

1 ) Simplest form - single table update

SQL code
  1. --It is confirmed that all customer_id less than 1000 in the customers table are 'Beijing'
  2. --Those less than 1000 are the old customers in the city before the company went to the whole country :)
  3. update customers
  4. set  city_name= 'Beijing'
  5. where customer_id<1000

2 ) Two-table (multi-table) association update  -- set is simple data (direct value), and only the connection in the where clause

SQL code
  1. --The data extracted this time are all VIPs, including new ones, so update the customer category by the way
  2. update  customers a  -- use an alias
  3. set  customer_type= '01'  --01 is vip, 00 is ordinary
  4. where exists (select 1
  5. from tmp_cust_city b
  6. where b.customer_id=a.customer_id
  7. )

 

3 ) Two-table (multi-table) associated update  --  the modified value is calculated from another table

SQL code
  1. update  customers a  -- use an alias
  2. set city_name=(select b.city_name from tmp_cust_city b where b.customer_id=a.customer_id)
  3. where exists (select 1
  4. from tmp_cust_city b
  5. where b.customer_id=a.customer_id
  6. )
  7. Optimization: Optimization of a single field, simplified to scan once
    7.1 SQL code
    1. update  customers a  -- use an alias
    2. set city_name=nvl((select b.city_name from tmp_cust_city b where b.customer_id=a.customer_id),a.city_name)
  8. --update more than 2 values ​​(fields )
  9. update  customers a  -- use an alias
  10. set (city_name,customer_type)=(select b.city_name,b.customer_type
  11. from tmp_cust_city b
  12. where b.customer_id=a.customer_id)
  13. where exists (select 1
  14. from tmp_cust_city b
  15. where b.customer_id=a.customer_id
  16. )

3的缺点,就是对表B进行两遍扫描;

 

 

 

4) 特殊情况的优化:

因为B表的纪录只有A表的20-30%的纪录数,且

 

A表使用INDEX的情况

 

 

使用cursor也许会比关联update带来更好的性能:

 

 

 

SQL 代码
  1. set serveroutput on
  2. declare
  3. cursor city_cur is
  4. select customer_id,city_name
  5. from tmp_cust_city
  6. order by customer_id;
  7. begin
  8. for my_cur in city_cur loop
  9. update customers
  10. set city_name=my_cur.city_name
  11. where customer_id=my_cur.customer_id;
  12. /** 此处也可以单条/分批次提交,避免锁表情况 **/
  13. -- if mod(city_cur%rowcount,10000)=0 then
  14. -- dbms_output.put_line('----');
  15. -- commit;
  16. -- end if;
  17. end loop;
  18. end;

5) 关联update的一个特例以及性能再探讨
Oracle
update语句语法中,除了可以update表之外,也可以是视图,所以有以下1个特例:

SQL 代码
  1. update (select a.city_name,b.city_name as new_name
  2. from customers a,
  3. tmp_cust_city b
  4. where b.customer_id=a.customer_id
  5. )
  6. set city_name=new_name


这样能避免对B表或其索引的2次扫描,但前提是 A(customer_id) b(customer_id)必需是unique index或primary key

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326350268&siteId=291194637