Optimize single update statement
Hi all, I've got a table with about 50 millions of rows (a spatial network...) and I have to issue an update statement without any where condition.
The statement is: UPDATE NODE SET ACTIVE='Y';
Which is the most efficient way to do this?
A single UPDATE statement, the forall loop or an incremental FOR loop with partial commit (each 1000 rows i.e.)?
Thanks
Lorenzo
Or a single MERGE statement.
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:6407993912330#57387981485901
You'd test with a subset before to see what performs fastest, ofcourse...
Similar Messages
-
How to convert pl/sql block into single update statement
Dear all gurus,
I have pl/sql block mention below, Can I convert this pl/sql block to single update statement if possible?
If not how to optimize this block?
Pleaese suggest.
thanks in advance.
Vijay
DECLARE
CURSOR vt_mlr_cursor IS Select master_key, user4 from vt_mlr Where USER4 is not null;
USERFIELD VARCHAR2(100);
C1 VARCHAR2(3); /* this will return location of first space = 12 */
C2 VARCHAR2(3); /* this will return location of second space = 20 */
C3 VARCHAR2(3); /* this will return location of third space = 28 */
C4 VARCHAR2(3); /* this will return location of forth space = 35 */
Field1 VARCHAR2(40); /* this will return FTMYFLXA04W */
Field2 VARCHAR2(10); /* this will return VPI0043 */
Field3 VARCHAR2(10); /* this will return VCI0184 */
Field4 VARCHAR2(10); /* this will return 005 */
Field5 VARCHAR2(10); /* this will return 00001 */
Field_2_n_3 VARCHAR2(25);
key VARCHAR2(10);
BEGIN
FOR vt_mlr_record IN vt_mlr_cursor
LOOP
key := vt_mlr_record.master_key;
USERFIELD := vt_mlr_record.user4;
C1 := INSTR(vt_mlr_record.user4,' ',1,1); /* this will return location of first space = 12 */
C2 := INSTR(vt_mlr_record.user4,' ',1,2); /* this will return location of second space = 20 */
C3 := INSTR(vt_mlr_record.user4,' ',1,3); /* this will return location of third space = 28 */
C4 := INSTR(vt_mlr_record.user4,' ',1,4); /* this will return location of forth space = 35 */
Field1 := SUBSTR(vt_mlr_record.user4,1,C1-1); /* this will return FTMYFLXA04W */
Field2 := SUBSTR(vt_mlr_record.user4,C1+4,C2-C1-4); /* this will return VPI0043 */
Field3 := SUBSTR(vt_mlr_record.user4,C2+4,C3-C2-4); /* this will return VCI0184 */
Field4 := SUBSTR(vt_mlr_record.user4,C3+4,C4-C3-4); /* this will return 005 */
Field5 := SUBSTR(vt_mlr_record.user4,C4+4,LENGTH(vt_mlr_record.user4)-C4-3); /* this will return 00001 */
Field_2_n_3 := Field2 || '/' || Field3;
/*DBMS_OUTPUT.PUT_LINE ('Current key is: ' || vt_mlr_record.master_key);*/
UPDATE vt_mlr
SET
aggregator_clli = Field1,
aggregator_vpi_vci = Field_2_n_3,
aggregator_slot = Field4,
aggregator_port = Field5
WHERE
master_key = vt_mlr_record.master_key;
END LOOP;
END;
/Hi Vijay,
Here's something to start with, you should be able to complete it.
First, combine your select and update statements:
update vt_mlr
set aggregator_clli = field1
,aggregator_vpi_vci = field_2_n_3
,aggregator_slot = field4
,aggregator_port = field5
where user4 is not null;Then put these two
C1 := INSTR(vt_mlr_record.user4,' ',1,1);
Field1 := SUBSTR(vt_mlr_record.user4,1,C1-1);into
Field1 := SUBSTR(vt_mlr_record.user4,1,INSTR(vt_mlr_record.user4,' ',1,1) -1);And put it into the update statement, removing reference to record
(I have also removed default values for position and occurrence in instr function):
update vt_mlr
set aggregator_clli = substr(user4, 1, instr(user4,' ') - 1)
,aggregator_vpi_vci = field_2_n_3
,aggregator_slot = field4
,aggregator_port = field5
where user4 is not null; I think you can do the rest from here ;-)
Regards
Peter -
Update multiple columns with single update statement..
HI all,
i am reading the columns value from different table but i want to update it with signle update statement..
such as how to update multiple columns (50 columns) of table with single update statement .. is there any sql statement available i know it how to do with pl/sql..As I understood, may be this. Here i am updating ename,sal, comm columns all at once.
SQL> select * from emp where empno=7369;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
7369 SMITH CLERK 7902 17/12/1980 12:00:00 800 20
SQL> UPDATE emp
2 SET ename = lower (ename),
3 sal = sal + 1000,
4 comm = 100
5 WHERE empno = 7369;
1 row updated.
SQL> select * from emp where empno=7369;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
7369 smith CLERK 7902 17/12/1980 12:00:00 1800 100 20
SQL> UPDATE emp
2 SET ename = (SELECT 'ABCD' FROM DUAL),
3 sal = (SELECT 1000 FROM DUAL),
4 comm = (SELECT 100 FROM DUAL)
5 WHERE empno = 7369;
1 row updated. -
I have 20 or more update statement like below, I am trying to get this as a single
update statement to make it easier, can someone pls help me?
Update Product
Set sku_id = (Select sku_id From Product_base
Where Product_Code ='WWT204')
Where sku_id = (Select sku_id From Product_base
Where Product_Code ='9HRC04');
Update Product
Set sku_id = (Select sku_id From Product_base
Where Product_Code ='WWT205')
Where sku_id = (Select sku_id From Product_base
Where Product_Code ='9HRC05');
Update Product
Set sku_id = (Select sku_id From Product_base
Where Product_Code ='WWT206')
Where sku_id = (Select sku_id From Product_base
Where Product_Code ='9HRC06');
etc...
etc..In general, it can't be done since it is possible sku_id updated by first UPDATE will be updated by second or third or... UPDATE. Assuming each UPDATE affects unique set of sku_id:
update product p
set sku_id = (
select (
select sku_id
from product_base pb2
where product_code = case pb1.product_base
when '9HRC04' then 'WWT204'
when '9HRC05' then 'WWT205'
when '9HRC06' then 'WWT206'
end
from product_base pb1
where pb1.sku_id = p.sku_id
and product_code in ('9HRC04','9HRC05','9HRC06')
where sku_id in (
select sku_id
from product_base
where product_code in ('9HRC04','9HRC05','9HRC06')
);SY. -
Updating multiple fields using a single update statement.
Hi All,
I am a beginner to Oracle. I have used the following Hint in an update query that is executed in Oracle 10G. We recently updated the Oracle to version 11g and when executing the query getting the following Error: ORA-01779: cannot modify a column which maps to a non key-preserved table. PFB the query. Please suggest me some ways that I can do to avoid this error.
UPDATE /*+ bypass_ujvc */
(SELECT t1.STG_DEL_CONDITION, t2.condition
FROM stg_reports_membenft_latest T1 JOIN (select ods_ssn_grp,sys_id, first_value(STG_DEL_CONDITION) over(PARTITION BY ods_ssn_grp,sys_id
ORDER BY STG_DEL_CONDITION DESC) AS
condition from stg_reports_membenft_latest) T2
ON T1.ods_ssn_grp = T2.ods_ssn_grp AND T1.SYS_ID=T2.SYS_ID ) x
SET x.STG_DEL_CONDITION = x.condition;
Thanks and Regards,
Karthik Sivakumar.I used the below query and got the Result.
Thank You all
MERGE INTO stg_reports_membenft_latest x1
USING (SELECT distinct ods_ssn_grp,
sys_id,
First_value(STG_DEL_CONDITION) OVER(partition BY ods_ssn_grp,sys_id
ORDER BY STG_DEL_CONDITION DESC)
AS condition
FROM stg_reports_membenft_latest) x2
ON ( x1.ods_ssn_grp = x2.ods_ssn_grp
AND x1.SYS_ID = x2.sys_id )
WHEN matched THEN
UPDATE SET x1.STG_DEL_CONDITION=x2.condition; -
Is their any limit on the number of column updates in a update statement!
Hello All,
Is their any limit on the number of columns to set in a single update statement.+
am using oracle 11g .
example :-
UPDATE FMLY SET as_comp1 = v_as_comp1 , as_comp2 = v_as_comp2, as_comp3 = v_as_comp3, as_comp4 = v_as_comp4 , as_comp5 = v_as_comp5 , perslt18 = v_perslt18 , persot64 = v_persot64 , fam_size = v_fam_size , numchild = total_children , C_AGE1 = v_c_age1, C_AGE2 = v_c_age2, C_AGE3 = v_c_age3, C_AGE4 = v_c_age4 WHERE FAMID = fmly_famid(i) ;
and also is it good practice to issue single update or multiple updates ?
example for the above update i can have multiple statements like .. does the performance matters if so which is good
UPDATE FMLY SET as_comp1 = v_as_comp1 , as_comp2 = v_as_comp2, as_comp3 = v_as_comp3, as_comp4 = v_as_comp4 , as_comp5 = v_as_comp5
WHERE FAMID = fmly_famid(i) ;
UPDATE FMLY SET perslt18 = v_perslt18 , persot64 = v_persot64 , fam_size = v_fam_size
WHERE FAMID = fmly_famid(i) ;
UPDATE FMLY SET numchild = total_children WHERE FAMID = fmly_famid(i) ;
UPDATE FMLY SET C_AGE1 = v_c_age1, C_AGE2 = v_c_age2, C_AGE3 = v_c_age3, C_AGE4 = v_c_age4 WHERE FAMID = fmly_famid(i) ;
thanks/kumar
Edited by: kumar73 on Sep 25, 2010 8:38 AMIf you can do it in a single SQL statement then you should do that.
Here's a mantra that I found to work out pretty good:
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:73891904732164 -
Need a help on Update statement
Hi All,
I Need a help in updating a table column. PFB my requirement.
Table1
ItemID OrgId Date
1 82 12/sep/2012
2 82 25/oct/2012
3 82 17/Nov/2012
4 82 22/Jan/2013
5 82 26/sep/2012
Table2
Itemid orgid Date1
1 82 23/sep/2012
2 82 25/Dec/2012
3 82 17/Sep/2012
4 82 22/Feb/2013
5 82 26/Oct/2012
Table3
Itemid orgid Date3
1 82 10/sep/2012
7 82 30/Dec/2012
3 82 12/Sep/2012
10 82 27/Feb/2013
5 82 29/Oct/2012
I Need to Update Date column of Table1 With Date3 of table3
If
Item and org combination is present in table3 and date column of table1 is less than Date3 of table3
Else
I need to Update with date2 of table2.Can we acheive this in a single update statement, can any one help me on this.
Thanks and regards,
Rakesh
Edited by: Venkat Rakesh on Sep 27, 2012 11:04 PMYou can probably also use MERGE:
--DROP TABLE table1;
--DROP TABLE table2;
--DROP TABLE table3;
ALTER SESSION SET nls_language = 'AMERICAN';
CREATE TABLE table1
itemid CHAR (1),
orgid CHAR (2),
thedate DATE
INSERT INTO table1 SELECT '1', '82', TO_DATE ('10/sep/2011', 'dd/mon/yyyy') FROM DUAL;
INSERT INTO table1 SELECT '2', '82', TO_DATE ('10/oct/2011', 'dd/mon/yyyy') FROM DUAL;
INSERT INTO table1 SELECT '3', '82', TO_DATE ('10/nov/2011', 'dd/mon/yyyy') FROM DUAL;
INSERT INTO table1 SELECT '4', '82', TO_DATE ('10/jan/2011', 'dd/mon/yyyy') FROM DUAL;
INSERT INTO table1 SELECT '5', '82', TO_DATE ('10/sep/2011', 'dd/mon/yyyy') FROM DUAL;-- won't be updated
CREATE TABLE table2
itemid CHAR (1),
orgid CHAR (2),
thedate DATE
INSERT INTO table2 SELECT '1', '82', TO_DATE ('01/sep/2012', 'dd/mon/yyyy') FROM DUAL;
INSERT INTO table2 SELECT '2', '82', TO_DATE ('01/dec/2012', 'dd/mon/yyyy') FROM DUAL;
INSERT INTO table2 SELECT '3', '82', TO_DATE ('01/sep/2012', 'dd/mon/yyyy') FROM DUAL;
INSERT INTO table2 SELECT '4', '82', TO_DATE ('01/feb/2012', 'dd/mon/yyyy') FROM DUAL;
CREATE TABLE table3
itemid CHAR (1),
orgid CHAR (2),
thedate DATE
INSERT INTO table3 SELECT '2', '82', TO_DATE ('30/dec/2009', 'dd/mon/yyyy') FROM DUAL; -- date less than table1, so picks from table2
INSERT INTO table3 SELECT '4', '82', TO_DATE ('30/mar/2013', 'dd/mon/yyyy') FROM DUAL; -- larger than table1 , so pick this date
-- table1 original data
SELECT * FROM table1;
-- merge new data
MERGE INTO table1
USING (SELECT NVL (t1.itemid, t2.itemid) itemid,
NVL (t1.orgid, t2.orgid) orgid,
t2.thedate prefdate ,
t1.thedate nextdate
FROM table2 t1
FULL OUTER JOIN
table3 t2
ON t1.itemid = t2.itemid AND t1.orgid = t2.orgid) dat
ON (dat.itemid = table1.itemid AND dat.orgid = table1.orgid)
WHEN MATCHED
THEN
UPDATE SET table1.thedate = (case when prefdate > table1.thedate then prefdate else nextdate end) ;
--table1 updated data
SELECT * FROM table1;OUTPUT:
Session altered.
Table created.
1 row created.
1 row created.
1 row created.
1 row created.
1 row created.
Table created.
1 row created.
1 row created.
1 row created.
1 row created.
Table created.
1 row created.
1 row created.
ITEMID ORGID THEDATE
1 82 10.09.2011
2 82 10.10.2011
3 82 10.11.2011
4 82 10.01.2011
5 82 10.09.2011
5 rows selected.
4 rows merged.
ITEMID ORGID THEDATE
1 82 01.09.2012
2 82 01.12.2012
3 82 01.09.2012
4 82 30.03.2013
5 82 10.09.2011
5 rows selected. -
Help need on update statements
Hi,
How can i write a single update statement instead of these 2 update statements
UPDATE ACCOUNT_TEMP SET REPO_ASSIGN_FLAG = 1
WHERE ARR_ID_ACCT IN
(SELECT LTRIM(ASR1.ARR_ID_ACCT)
FROM ODS_ACCT_STAT_REL ASR1
WHERE ASR1.ACCT_STAT_TYPE = 'SECONDARY'
AND ASR1.ACCT_STAT_CDE IN ('RA','RV'))
UPDATE ACCOUNT_TEMP SET LE_LI_FLAG = 1
WHERE ARR_ID_ACCT IN
(SELECT LTRIM(ASR1.ARR_ID_ACCT)
FROM ODS_ACCT_STAT_REL ASR1
WHERE ASR1.ACCT_STAT_TYPE = 'SECONDARY'
AND ASR1.ACCT_STAT_CDE IN ( 'LI','LV'))
Thanks for your helpupdate account_temp
set repo_assign_flag = case when
arr_id_action in (select ltrim(asr1.apr_id_acct)
from ods_acct_stat_relasr1
where asr1.acct_stat_type = 'SECONDARY'
and asr1.acct_stat_cde in ('RA','RV') then 1
set LE_LI_FLAG = case when
arr_id_acct in (select ltrim(asr1.arr_id_acct)
from ods_acct_stat_rel.asr1
where asr1.acct_stat_type = 'SECONDARY'
and asr1.acct_stat_cde in ('LI', 'LV') THEN 1
;But remember this code will have performace issues dont combine your updated statements if you dont need to.
Code not tested . . .
HTH
Ghulam -
How to tune the Update statement for 20 million rows
Hi,
I want to update 20 million rows of a table. I wrote the PL/SQL code like this:
DECLARE
v1
v2
cursor C1 is
select ....
BEGIN
Open C1;
loop
fetch C1 bulk collect into v1,v2 LIMIT 1000
exit when C1%NOTFOUND;
forall i in v1.first..v1.last
update /*+INDEX(tab indx)*/....
end loop;
commit;
close C1;
END;
The above code took 24 mins to update 100k records, so for around 20 million records it will take 4800 mins (80 hrs).
How can I tune the code further ? Will a simple Update statement, instead of PL/SQL make the update faster ?
Will adding few more hints help ?
Thanks for your suggestions.
Regards,
Yogini JoshiHello
You have implemented this update in the slowest possible way. Cursor FOR loops should be absolute last resort. If you post the SQL in your cursor there is a very good chance we can re-code it to be a single update statement with a subquery which will be the fastest possible way to run this. Please remember to use the {noformat}{noformat} tags before and after your code so the formatting is preserved.
David -
Can I use a select and update statement in a single jsp file?
I want to update the BUY table everytime I would add a SELL transaction.....I want to minus the stocks that I sold to those that Ive bought before.....
note: I used a seperate table in BUY and SELL transaction
After I Have added a transaction, I want to update the buy table. This is my problem, can I used both SELECT and UPDATE statement at the same time in a single jsp file for example like this:
select * from test, test1;
update test
set total_shares=total_shares-Stotal;
where stock_code=Scode AND name_broker=Sbroker;
Can i have both of these statements in the same jsp file in oder to update the buy table?
Or can anyone suggest how can process that update?THANKS!
--------------------Can i have both of these statements in the same jsp file in oder to update the buy table?Yes. But wouldn't it have been easier just to try it?
-
Update statement takes lot of time . Need help in optimization.
Hi,
I need to update values from table ARPU_2009_2010 to table TST_MICRO_SEG_PREP.
Table ARPU_2009_2010 contains around 400000 records. Table TST_MICRO_SEG_PREP contains 374000 customers. I need to update values for each customer in the table TST_MICRO_SEG_PREP.
Please find below query used:
UPDATE TST_MICRO_SEG_PREP a
SET
ARPU_2009_2010_REV=(select case when cnt>0 then round((sum(total_rev)/cnt),2) else 0 end arpu from ARPU_2009_2010 b
where a.subno=b.subno
group by subno,cnt)
This query takes more than 4 hours to execute. All tables used are having proper index.
Kindly suggest an alternative for this.
Thanks,
Kabilan
Edited by: 946887 on Jul 16, 2012 11:44 PM>
UPDATE table1 X
SET
ARPU=(select case when cnt>0 then round((sum(total_rev)/cnt),2) else 0 end arpu from table2 Y
where X.subno=Y.subno
group by subno,cnt)
>
Are you intending to update all the 400K rows in table1 ? If not, then you have to rewrite the query.
>
This query takes more than 4 hours to execute.
>
Did you try to monitor what it's doing when the query is getting executed.
>
I tried to execute using stored procedures and sp also takes much time.
>
What makes you to think that stored procedure will execute more efficiently compared to a single DML statement ?
>
Kindly suggest an alternative for this.
>
As mentioned in the earlier post try to follow the guidelines. Only then it will be feasible to suggest some alternatives by looking at some metrics.
Thanks
Raj -
Update all null columns value in single row statement
4) Write a single SQL statement to update all the columns of a table to have -9 instead of null value
e.g:
Before update:
C1 C2 C3
null 9 null
10 null 88
12 8 0
After update:
C1 C2 C3
-9 9 -9
10 -9 88
12 8 0
ThanksHi,
Update < table name >
set column name = nvl(column name, -9),
column name = nvl(column name, -9)
Regards
Message was edited by:
Seshu -
Updates using single SQL Update statement.
Hi Guys,
I had an interview... and was not able to give an answer of one of the question.
Given the emp table... need to update the salary with following requirement using one SQL statement...
1. Update salary+1000 for those employees who have salary between 500 and 1000
2. Update salary+500 for those employees who have salary between 1001 and 1500
Both above requirement should be done by using only one SQL update statement... can some one tell me how to do it?update emp
set salary = case when salary between 500 and 1000
then salary + 1000
when salary between 1001 and 1500
then salary + 500
end;Regards
Arun -
Explain plan on Update statement in function
All,
I have an update statement in a function and my explain plan shows:
"Optimizer" "Cost" "Cardinality" "Bytes"
"UPDATE STATEMENT" "ALL_ROWS" "2" "1" "7"
"UPDATE user.<table_name>" "" "" "" ""
"INDEX(UNIQUE SCAN) <table_name>.<PK_column_cons>" "ANALYZED" "1" "1" "7"
Filtering is on index unique column, but cost is 1 what does that mean?
do i need to change my update statement in function?
Any ideas?
Regards,
~ORAThe cost is the optimizer's measure of how much effort it will take to execute the statement. For any statement the optimizer will evaluate a number of execution plans and choose the one with the lowest cost. I wouldn't worry too much about what it actually "means". However if you want to understand this subject in a lot more detail I would recommend the book Cost-Based Oracle Fundamentals by Jonathan Lewis.
For your update statement the optimizer has chosen to access a single row by the primary key index, which is probably good enough, so you should not need to change it.
The only faster way to access the data would be to use the row's ROWID directly. You would need to have fetched this explicitly in a previous SELECT statement, or you could use it implicitly with the WHERE CURRENT OF syntax for a cursor opened with FOR UPDATE. -
Doubt about UPDATE STAT COLUMN
Hi,
I have a doubt of when to execute update stat:
i create this SQL to generate an SQL script to generate update stat for all my tables:
select 'UPDATE STAT ' || schemaname || '.' || tablename || ' ESTIMATE SAMPLE 20 PERCENT' from tables where schemaname = 'DBUSER' and not tablename like 'JDBC%' AND type = 'TABLE'
and created this SQL to generate an SQL script for update stat for all columns.
select 'UPDATE STAT COLUMN(*) FOR ' || schemaname || '.' || tablename || ' ESTIMATE SAMPLE 20 PERCENT' from tables where schemaname = 'DBUSER' and not tablename like 'JDBC%' AND type = 'TABLE'
my doubt is i really need run that second script? or the UPDATE STAT for table dont UPDATE STAT for all columns?
thanks for any insight
Clóvis> my doubt is i really need run that second script? or the UPDATE STAT for table dont UPDATE STAT for all columns?
Hi Clovis,
hmm... good question.
There are a few things to know about the UPDATE STAT command here.
1) It will always generate statistics for key or indexed columns.
2) The optimizer won't be able to generate a better plan when there are column statistics for non-indexed columns present.
3) The command will also collect column statistics for all columns that already have statistics.
The direct effect of 3) is that by running your second command just once - all column statistics will always be collected.
Since you can easily change the default sample size for your tables via
ALTER TABLE SAMPLE SIZE 20 PERCENT
I would say: drop your script and just use
UPDATE STAT DBUSER.* ESTIMATE
This single command would lead to the same statistics as your script does.
And if you really, really want to leave out the JDBC tables - then just set their default sample size to 0 and they will be ignored by the UPDATE STAT command.
regards,
Lars
Maybe you are looking for
-
ML81N Negative Quantity Posting for Credit or Difference Adjustments.
ECC 5.0 - DIMP This is a VERY, VERY common situation at nearly all companies where a credit or small difference may occur between the invoice amount and the SES. Reversing / canceling and reentering documents, along with all of the additional accoun
-
Acrobat X Standard from Dell (download)
I have a 3 month old Dell XPS 15 running win7 64 bit Home Premium. At time of purchase I had the option of having Acrobat X (& Distiller) pre installed. Now when purchasing this is £20 but when i purchased my XPS it was on offer for a limited period
-
Change background to white on headshot. new to iPhoto. thanks
change background to white on headshot. new to iPhoto. thanks
-
WBS data distribution for IDOC-PI-JDBC with system status 'CRTD' not working.
Hello Experts, I am busy with a project where the PS project creation and updates should be transfered to the external legacy system through IDOC-PI-JDBC scenario. I am using the BAPI_PROJECT_MAINTAIN for this process. This scenario is working fine w
-
RoboForm Extension is missing on both computers
I have installed the RoboForm Extension on both my computers. The Roboform icon; along with all it's options, usually displays, as a toolbar, under my Bookmarks toolbar. It was there this morning because I used it several times. This afternoon, when