Need to tune this Update statement.
Hi..
I have an update which I suspect is performing bad.
UPDATE
PS_OI_RNV_RCN_RECV R
SET (VOUCHER_ID, VOUCHER_LINE_NUM) =
(SELECT
M.VOUCHER_ID ,
M.VOUCHER_LINE_NUM
FROM
PS_VCHR_RECV_MTCH M
WHERE
M.BUSINESS_UNIT = R.BUSINESS_UNIT_GL
AND M.BUSINESS_UNIT_PO = R.BUSINESS_UNIT
AND M.RECEIVER_ID = R.RECEIVER_ID
AND M.RECV_LN_NBR = R.RECV_LN_NBR
AND (M.RECEIVER_ID, M.RECV_LN_NBR) IN ( SELECT M3.RECEIVER_ID ,M3.RECV_LN_NBR
FROM PS_VCHR_RECV_MTCH M3
WHERE
M3.BUSINESS_UNIT =R.BUSINESS_UNIT_GL
AND M3.BUSINESS_UNIT_PO = R.BUSINESS_UNIT
AND M3.RECEIVER_ID = R.RECEIVER_ID
AND M3.RECV_LN_NBR = R.RECV_LN_NBR
HAVING COUNT(*) = :"SYS_B_0"
GROUP BY M3.RECEIVER_ID , M3.RECV_LN_NBR
WHERE
R.USERID = :"SYS_B_1"
AND R.RUN_CNTL_ID = :"SYS_B_2"
AND R.VOUCHER_ID = :"SYS_B_3"
AND R.OI_RNV_STATUS = :"SYS_B_4"
AND EXISTS ( SELECT VOUCHER_ID ,VOUCHER_LINE_NUM FROM PS_VCHR_RECV_MTCH M2
WHERE
M2.BUSINESS_UNIT = R.BUSINESS_UNIT_GL
AND M2.BUSINESS_UNIT_PO = R.BUSINESS_UNIT
AND M2.RECEIVER_ID = R.RECEIVER_ID
AND M2.RECV_LN_NBR = R.RECV_LN_NBR
AND (M2.RECEIVER_ID, M2.RECV_LN_NBR) IN ( SELECT M4.RECEIVER_ID ,M4.RECV_LN_NBR
FROM PS_VCHR_RECV_MTCH M4
WHERE M4.BUSINESS_UNIT = R.BUSINESS_UNIT_GL
AND M4.BUSINESS_UNIT_PO = R.BUSINESS_UNIT
AND M4.RECEIVER_ID = R.RECEIVER_ID
AND M4.RECV_LN_NBR = R.RECV_LN_NBR
HAVING COUNT(*) = :"SYS_B_5"
GROUP BY M4.RECEIVER_ID , M4.RECV_LN_NBR
)Plan for this Statement is
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | UPDATE STATEMENT | | 1 | 59 | 7413 (1)| 00:01:29 |
| 1 | UPDATE | PS_OI_RNV_RCN_RECV | | | | |
|* 2 | FILTER | | | | | |
|* 3 | TABLE ACCESS FULL | PS_OI_RNV_RCN_RECV | 1 | 59 | 750 (1)| 00:00:09 |
|* 4 | INDEX RANGE SCAN | PS_VCHR_RECV_MTCH | 1 | 27 | 1110 (1)| 00:00:14 |
|* 5 | FILTER | | | | | |
| 6 | SORT GROUP BY NOSORT| | 1 | 27 | 1110 (1)| 00:00:14 |
|* 7 | INDEX RANGE SCAN | PS_VCHR_RECV_MTCH | 1 | 27 | 1110 (1)| 00:00:14 |
|* 8 | INDEX RANGE SCAN | PS_VCHR_RECV_MTCH | 1 | 40 | 1110 (1)| 00:00:14 |
|* 9 | FILTER | | | | | |
| 10 | SORT GROUP BY NOSORT | | 1 | 27 | 1110 (1)| 00:00:14 |
|* 11 | INDEX RANGE SCAN | PS_VCHR_RECV_MTCH | 1 | 27 | 1110 (1)| 00:00:14 |
Predicate Information (identified by operation id):
2 - filter( EXISTS (SELECT 0 FROM "PS_VCHR_RECV_MTCH" "SYS_ALIAS_10" WHERE
"M2"."BUSINESS_UNIT"=:B1 AND "M2"."RECEIVER_ID"=:B2 AND "M2"."RECV_LN_NBR"=:B3 AND
"M2"."BUSINESS_UNIT_PO"=:B4 AND EXISTS (SELECT 0 FROM "PS_VCHR_RECV_MTCH" "M4" WHERE
"M4"."BUSINESS_UNIT"=:B5 AND "M4"."RECEIVER_ID"=:B6 AND "M4"."RECV_LN_NBR"=:B7 AND
"M4"."BUSINESS_UNIT_PO"=:B8 GROUP BY "M4"."RECEIVER_ID","M4"."RECV_LN_NBR" HAVING
PLAN_TABLE_OUTPUT
"M4"."RECEIVER_ID"=:B9 AND "M4"."RECV_LN_NBR"=:B10 AND COUNT(*)=TO_NUMBER(:SYS_B_5))))
3 - filter("R"."VOUCHER_ID"=:SYS_B_3 AND "R"."RUN_CNTL_ID"=:SYS_B_2 AND
"R"."OI_RNV_STATUS"=:SYS_B_4 AND "R"."USERID"=:SYS_B_1)
4 - access("M2"."BUSINESS_UNIT"=:B1 AND "M2"."RECEIVER_ID"=:B2 AND
"M2"."RECV_LN_NBR"=:B3 AND "M2"."BUSINESS_UNIT_PO"=:B4)
filter("M2"."RECEIVER_ID"=:B1 AND "M2"."RECV_LN_NBR"=:B2 AND
"M2"."BUSINESS_UNIT_PO"=:B3 AND EXISTS (SELECT 0 FROM "PS_VCHR_RECV_MTCH" "M4" WHERE
"M4"."BUSINESS_UNIT"=:B4 AND "M4"."RECEIVER_ID"=:B5 AND "M4"."RECV_LN_NBR"=:B6 AND
"M4"."BUSINESS_UNIT_PO"=:B7 GROUP BY "M4"."RECEIVER_ID","M4"."RECV_LN_NBR" HAVING
"M4"."RECEIVER_ID"=:B8 AND "M4"."RECV_LN_NBR"=:B9 AND COUNT(*)=TO_NUMBER(:SYS_B_5)))
5 - filter("M4"."RECEIVER_ID"=:B1 AND "M4"."RECV_LN_NBR"=:B2 AND
COUNT(*)=TO_NUMBER(:SYS_B_5))
7 - access("M4"."BUSINESS_UNIT"=:B1 AND "M4"."RECEIVER_ID"=:B2 AND
"M4"."RECV_LN_NBR"=:B3 AND "M4"."BUSINESS_UNIT_PO"=:B4)
filter("M4"."RECEIVER_ID"=:B1 AND "M4"."RECV_LN_NBR"=:B2 AND
"M4"."BUSINESS_UNIT_PO"=:B3)
8 - access("M"."BUSINESS_UNIT"=:B1 AND "M"."RECEIVER_ID"=:B2 AND
"M"."RECV_LN_NBR"=:B3 AND "M"."BUSINESS_UNIT_PO"=:B4)
filter("M"."RECEIVER_ID"=:B1 AND "M"."RECV_LN_NBR"=:B2 AND
"M"."BUSINESS_UNIT_PO"=:B3 AND EXISTS (SELECT 0 FROM "PS_VCHR_RECV_MTCH" "M3" WHERE
"M3"."BUSINESS_UNIT"=:B4 AND "M3"."RECEIVER_ID"=:B5 AND "M3"."RECV_LN_NBR"=:B6 AND
"M3"."BUSINESS_UNIT_PO"=:B7 GROUP BY "M3"."RECEIVER_ID","M3"."RECV_LN_NBR" HAVING
"M3"."RECEIVER_ID"=:B8 AND "M3"."RECV_LN_NBR"=:B9 AND COUNT(*)=TO_NUMBER(:SYS_B_0)))
9 - filter("M3"."RECEIVER_ID"=:B1 AND "M3"."RECV_LN_NBR"=:B2 AND
COUNT(*)=TO_NUMBER(:SYS_B_0))
11 - access("M3"."BUSINESS_UNIT"=:B1 AND "M3"."RECEIVER_ID"=:B2 AND
"M3"."RECV_LN_NBR"=:B3 AND "M3"."BUSINESS_UNIT_PO"=:B4)
PLAN_TABLE_OUTPUT
filter("M3"."RECEIVER_ID"=:B1 AND "M3"."RECV_LN_NBR"=:B2 AND
"M3"."BUSINESS_UNIT_PO"=:B3)
DBMS_METADATA.GET_DDL('INDEX','PS_VCHR_RECV_MTCH')
CREATE UNIQUE INDEX "SYSADM"."PS_VCHR_RECV_MTCH" ON "SYSADM"."PS_VCHR_RECV_MTC
H" ("BUSINESS_UNIT", "VOUCHER_ID", "VOUCHER_LINE_NUM", "BUSINESS_UNIT_RECV", "RE
CEIVER_ID", "RECV_LN_NBR", "RECV_SHIP_SEQ_NBR", "BUSINESS_UNIT_PO", "PO_ID", "LI
NE_NBR", "SCHED_NBR")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 40960 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "PSINDEX"
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 0 0 0
Execute 1 2007.68 2012.83 2 182564670 4260 4070
Fetch 0 0.00 0.00 0 0 0 0
total 2 2007.68 2012.83 2 182564670 4260 4070Thanks...
Edited by: Oceaner on May 24, 2012 7:15 AM
Hi Gokul,
in case of no statistics most likely the optimizer would do a dynamic sampling, so ironically, no statistics is often better than statistics.
It could be that some of the tables is used as a temp table (i.e. is filled with data to carry out some operations, and then purged), in which case the stats job could've caught it when it was empty. But even if the cardinalities would have been fine, I don't really think the optimizer has a lot of options with the query as is stands, because the aggregate subqueries restrict the ability of the optimizer to apply query transforms.
Still, worth a shot to check if stats are accurate -- that's an easy thing to do and couldn't possibly do any harm.
Best regards,
Nikolay
Similar Messages
-
How to tune this update statement?
Hello,
I have to solve the following task:
Update every row in table A which has an appropriate row in table B and log what you have done in a log-table.
It is possible that there are more than one fitting rows in table A for a row in table B.
My first approach is looping over the table B and doing an update of table A for every entry in table B.
This works and looks like this:
Table A:
PK number (This is the primary key of this table)
KEY number
Table B:
KEY_OLD number
KEY_NEW number
Log table:
PK number
KEY_OLD number
KEY_NEW number
declare
TYPE PK_TAB_TYPE IS TABLE OF number INDEX BY BINARY_INTEGER;
v_tab_PK PK_TAB_TYPE;
v_empty_tab_PK PK_TAB_TYPE;
begin
for v_rec in (select * from table_B) loop
v_tab_PK := v_empty_tab_PK; /* clearing the array */
update table_A
set KEY = v_rec.KEY_NEW
where (KEY = v_rec.KEY_OLD)
returning PK bulk collect into v_tab_PK;
if (v_tab_PK.count > 0) then
for i in v_tab_PK.first..v_tab_PK.last loop
insert into TMP_TAB_LOG(PK, KEY_OLD, KEY_NEW)
values (v_tab_PK(i), v_rec.KEY_OLD, v_rec.KEY_NEW);
end loop;
end if;
end loop;
end;Because the table B can have up to 500.000 entries (and the table A has even more entries) this solution will cause many update-statements.
So I am looking for a solution which has better performance.
My second approach was using an correlated update and looks like this:
declare
TYPE PK_TAB_TYPE IS TABLE OF number INDEX BY BINARY_INTEGER;
v_tab_PK PK_TAB_TYPE;
v_empty_tab_PK PK_TAB_TYPE;
v_tab_NewKey PK_TAB_TYPE;
begin
v_tab_PK := v_empty_tab_PK; /* clear the arrays */
v_tab_NewKey := v_empty_tab_PK;
update table_A a
set KEY = (select KEY_NEW from table_B where (KEY_OLD = a.KEY))
where exists (select 'x' as OK
from table_B
where (KEY_OLD = a.KEY)
returning PK, KEY bulk collect into v_tab_PK, v_tab_NewKey;
if (v_tab_PK.count > 0) then
for i in v_tab_PK.first..v_tab_PK.last loop
insert into TMP_TAB_LOG_DUB(PK, KEY_OLD, KEY_NEW)
values (v_tab_PK(i), null, v_tab_NewKey(i));
end loop;
end if;
end;Now I have only one update statement.
The only thing missing in this second approach is the old KEY before the update in the log table.
But I have no idea how to get the old value.
Is there a possibility to modify this second approach to get the old value of the KEY before the update to write it in the log-table?
And now I need your help:
What is the best way to get a performant solution for my task?
Every help appreciated.
Regards HartmutBelow is a script you can run in another testing schema to do the update with logging..... I have created the tables (A and B) with primary key constraints defined...
create table table_a(pk number primary key
, key number);
create table table_b(key_old number primary key
, key_new number);
create table TMP_TAB_LOG_DUB(pk number primary key
, key_old number
, key_new number);
---------insert test data
insert into table_a values(1,2);
insert into table_a values(2,2);
insert into table_a values(3,2);
insert into table_a values(11,1);
insert into table_a values(12,1);
insert into table_a values(13,1);
insert into table_a values(21,4);
insert into table_a values(22,4);
insert into table_a values(23,4);
commit;
insert into table_b values(1,3);
insert into table_b values(4,2);
commit;
----- insert to log
insert into TMP_TAB_LOG_DUB(PK, KEY_OLD, KEY_NEW)
select a.pk
, a.key as key_old
, b.key_new as key_new
from table_a a
join table_b b on a.key = b.key_old;
----- update table_a
update(select a.pk
, a.key as key_old
, b.key_new as key_new
from table_a a
join table_b b on a.key = b.key_old)
set key_old = key_new;
commit; -
How to automate this update statement
Hello:
I need to convert this update statement to a pl/sql procedure so that I can update this for each mk_product_id at a time because the primary update table has 80 million lines, If I do this for one mk_product_id is very fast, I need to update closely 2 million lines for month_id =55
update processor a set a.mkrptqty =
(select b.mkqty*p.rpt_conv_factor
from
processor b,
product p
where a.mk_record_id = b.mk_record_id
and a.mk_line_nbr = b.mk_line_nbr
and b.mk_product_id = p.part_code
and a.mk_product_id = '480'
and b.month_id = 55)
where
a.month_id = 55
and a.mk_product_id = '480'
Thanks,
MohanPL/SQL is slower than SQL.
Keep your update as a single large update statement, but better correlate your inner select with your outer table:
UPDATE processor a
SET a.mkrptqty =
(SELECT b.mkqty*p.rpt_conv_factor
FROM processor b,
product p
WHERE a.mk_record_id = b.mk_record_id
AND a.mk_line_nbr = b.mk_line_nbr
AND b.mk_product_id = p.part_code
AND a.month_id = b.month_id
WHERE a.month_id = 55
AND a.mk_product_id = '480';As you can see in the above code I correleated processor b completely with processor a from the outer update statement. But in the process noticed that you could probably completely dispose of processor b as noted below:
UPDATE processor a
SET a.mkrptqty =
(SELECT a.mkqty*p.rpt_conv_factor
FROM product p
WHERE a.mk_product_id = p.part_code
WHERE a.month_id = 55
AND a.mk_product_id = '480';Please note that neither of these pieces of code have been tested as I don't have relevant tables at hand to test on.
To update many mk_product_id's at a time just use the IN operator providing it with either a select list, or list of values:
UPDATE processor a
SET a.mkrptqty =
(SELECT a.mkqty*p.rpt_conv_factor
FROM product p
WHERE a.mk_product_id = p.part_code
WHERE a.month_id = 55
AND a.mk_product_id in ('480','481');or
WHERE (a.month_id, a.mk_product_id)
in ((55,'480'), (65,'481'));or
WHERE (a.month_id, a.mk_product_id)
in (select month_id, mk_product_id from some_table where some_conditions = 'are met');Edited by: Sentinel on Sep 17, 2008 2:25 PM -
Help with this update statement..
Hi everyone,
I am trying to update a column in a table .I need to update that column
with a function that takes patient_nbr and type_x column values as a parameter.
That table has almost "300,000" records. It is taking long time to complete
almost 60 min to 90 min.
Is it usual to take that much time to update that many records?
I dont know why it is taking this much time.Please help with this update statement.
select get_partner_id(SUBSTR(patient_nbr,1,9),type_x) partner_id from test_load;
(it is just taking 20 - 30 sec)
I am sure that it is not the problem with my function.
I tried the following update and merge statements .Please correct me if i am wrong
in the syntax and give me some suggestions how can i make the update statement fast.
update test_load set partner_id = get_partner_id(SUBSTR(patient_nbr,1,9),type_x);
merge into test_load a
using (select patient_nbr,type_x from test_load) b
on (a.patient_nbr = b.patient_nbr)
when matched
then
update
set a.partner_id = get_partner_id(SUBSTR(b.patient_nbr,1,9),b.type_x);
there is a index on patient_nbr column
and the statistics are gathered on this table.Hi Justin,
As requested here are the explain plans for my update statements.Please correct if i am doing anything wrong.
update test_load set partner_id = get_partner_id(SUBSTR(patient_nbr,1,9),type_x);
"PLAN_TABLE_OUTPUT"
"Plan hash value: 3793814442"
"| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |"
"| 0 | UPDATE STATEMENT | | 274K| 4552K| 1488 (1)| 00:00:18 |"
"| 1 | UPDATE | TEST_LOAD | | | | |"
"| 2 | TABLE ACCESS FULL| TEST_LOAD | 274K| 4552K| 1488 (1)| 00:00:18 |"
merge into test_load a
using (select patient_nbr,type_x from test_load) b
on (a.patient_nbr = b.patient_nbr)
when matched
then
update
set a.partner_id = get_partner_id(SUBSTR(b.patient_nbr,1,9),b.type_x);
"PLAN_TABLE_OUTPUT"
"Plan hash value: 1188928691"
"| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |"
"| 0 | MERGE STATEMENT | | 274K| 3213K| | 6660 (1)| 00:01:20 |"
"| 1 | MERGE | TEST_LOAD | | | | | |"
"| 2 | VIEW | | | | | | |"
"|* 3 | HASH JOIN | | 274K| 43M| 7232K| 6660 (1)| 00:01:20 |"
"| 4 | TABLE ACCESS FULL| TEST_LOAD | 274K| 4017K| | 1482 (1)| 00:00:18 |"
"| 5 | TABLE ACCESS FULL| TEST_LOAD | 274K| 40M| | 1496 (2)| 00:00:18 |"
"Predicate Information (identified by operation id):"
" 3 - access("A"."patient_nbr"="patient_nbr")"Please give some suggestions..
what's the best approach for doing the updates for huge tables?
Thanks -
HT6147 Do I need to do this update if I am still on one of the iOS 6's?
I am not sure if I need to download this update or not. I have an IPhone 4s that is running one of the iOS 6's.
Ok, this is really weird. It seems that at some point, the iOS 7 was forced onto my phone. This phone is new to me, and for the first few weeks, in settings, it was asking me to update to the iOS 7 which I would not do because I read that it is glitchy with the 4s. The update came out a few days ago, and when I just checked which version of iOS I was running, it was 7 so I just started the update. I'm not sure how the iOS 7 got on my phone.
-
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. -
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 -
Hi
I dont know anything about tuning
can anybody help to tune this query
SQL> set autotrace traceonly explain
SQL> select count(*) from ibs_x_t_receipts c
2 where exists
3 (Select 1 from ibs_s_i_doc_receipt a,ibs_x_t_bill b
4 where A.app_fr_doc_no = c.receipt_no
5 and a.app_to_doc_no = b.doc_no
6 and a.app_to_tr_type = 'TRN001'
7 and A.app_fr_tr_type = 'TRN002'
8 and b.bill_month <= '31-dec-2008'
9 and b.balance_ser_amt = 0
10 and b.balance_tax_amt = 0)
11 /
Execution Plan
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=212880 Card=1 Byte
s=21)
1 0 SORT (AGGREGATE)
2 1 NESTED LOOPS (Cost=212880 Card=1 Bytes=21)
3 2 VIEW OF 'VW_SQ_1' (VIEW) (Cost=212878 Card=1 Bytes=14)
4 3 HASH (UNIQUE)
5 4 NESTED LOOPS
6 5 NESTED LOOPS (Cost=212878 Card=1 Bytes=66)
7 6 VIEW OF 'index$_join$_002' (VIEW) (Cost=30021
Card=91387 Bytes=3564093)
8 7 HASH JOIN
9 8 INDEX (RANGE SCAN) OF 'SIDOC_INDX1' (INDEX
) (Cost=171215 Card=91387 Bytes=3564093)
10 8 INDEX (RANGE SCAN) OF 'SIDOC_INDX2' (INDEX
) (Cost=366130 Card=91387 Bytes=3564093)
11 6 INDEX (UNIQUE SCAN) OF 'ITL_PK2' (INDEX (UNIQU
E)) (Cost=1 Card=1)
12 5 TABLE ACCESS (BY INDEX ROWID) OF 'IBS_X_T_BILL'
(TABLE) (Cost=2 Card=1 Bytes=27)
13 2 INDEX (UNIQUE SCAN) OF 'RECEIPTS_PK2' (INDEX (UNIQUE))
(Cost=1 Card=1 Bytes=7)it is running like anything, i didn't get the result.
Please help me
kanish--untested
SELECT COUNT (*)
FROM ibs_x_t_receipts c
WHERE EXISTS (
SELECT 1
FROM ibs_s_i_doc_receipt a
WHERE a.app_fr_doc_no = c.receipt_no
AND a.app_to_tr_type = 'TRN001'
AND a.app_fr_tr_type = 'TRN002'
AND EXISTS (
SELECT 1
FROM ibs_x_t_bill b
WHERE a.app_to_doc_no = b.doc_no
AND b.bill_month <= '31-dec-2008'
AND b.balance_ser_amt = 0
AND b.balance_tax_amt = 0))regards,
friend
Edited by: most wanted!!!! on Apr 17, 2012 3:51 AM -
What is wrong with this update statement
Hi all,
I am trying to create a simple update program that allows user to enter table name, key fields and one field to update and its value.
But report goes into dump at update statement?
Here is the code:
REPORT ZTABLE_UPDATE.
parameters: tabname(18).
PARAMETERS: key1(15),"use at where condition
key1val(20),
key2(15),"use at where condition
key2val(20),
field2(15)."field to be updated
PARAMETERS: yenideg1(20),
yenideg2(20).
CONDENSE: tabname, field2,
yenideg1, yenideg2,
key1val, key2val,
key1, key2.
data: wa like tabname.
*update (tabname) SET field2 = yenideg1*
*WHERE key1 like key1val and key2 like key2val.*if sy-subrc eq 0.
SELECT SINGLE * FROM (tabname) INTO wa
WHERE key1 like key1val
and key2 like key2val.
WRITE / wa. "to test whether replacement is ok.
endif.
Thanks in advance.
DenizHi:
follows is ok:
DATA: dy_table TYPE REF TO data,
dy_line TYPE REF TO data,
ifc TYPE lvc_t_fcat,
xfc TYPE lvc_s_fcat.
DATA: it_clrs_fields LIKE TABLE OF dfies WITH HEADER LINE.
DATA: cond(72) TYPE c,
itab LIKE TABLE OF cond,
itab2 LIKE TABLE OF cond.
FIELD-SYMBOLS: <dyn_table> TYPE STANDARD TABLE,
<dyn_wa>,
<dyn_field>,
<fs>.
PARAMETERS: tabname TYPE ddobjname OBLIGATORY.
PARAMETERS: key1(15) OBLIGATORY,"use at where condition
key1val(20) OBLIGATORY,
key2(15),"use at where condition
key2val(20),
field2(15)."field to be updated
PARAMETERS: yenideg1(20),
yenideg2(20).
***START
CONDENSE: tabname, field2,
yenideg1, yenideg2,
key1val, key2val,
key1, key2.
CALL FUNCTION 'DDIF_FIELDINFO_GET'
EXPORTING
tabname = tabname
TABLES
dfies_tab = it_clrs_fields[]
FIXED_VALUES =
EXCEPTIONS
not_found = 1
internal_error = 2
OTHERS = 3
LOOP AT it_clrs_fields .
MOVE-CORRESPONDING it_clrs_fields TO xfc.
APPEND xfc TO ifc.
CLEAR: xfc.
ENDLOOP.
CALL METHOD cl_alv_table_create=>create_dynamic_table
EXPORTING
it_fieldcatalog = ifc
IMPORTING
ep_table = dy_table.
ASSIGN dy_table->* TO <dyn_table>.
CREATE DATA dy_line LIKE LINE OF <dyn_table>.
ASSIGN dy_line->* TO <dyn_wa>.
CLEAR COND.
CONCATENATE key1 ' = ''' key1val '''' 'AND' INTO cond.
APPEND cond TO itab.
CLEAR COND.
CONCATENATE key2 ' = ''' key2val '''' INTO cond.
APPEND cond TO itab.
SELECT *
INTO <dyn_wa>
FROM (tabname)
WHERE (itab).
ENDSELECT.
IF sy-subrc <> 0.
WRITE / 'no this data in dbtab'.
EXIT.
ENDIF.
CLEAR COND.
CONCATENATE field2 ' = ''' yenideg1 '''' INTO cond.
UPDATE (tabname) SET (cond)
WHERE (itab).
IF sy-subrc EQ 0.
SELECT SINGLE * FROM (tabname) INTO <dyn_wa>
WHERE (itab).
WRITE / <dyn_wa>. "to test whether replacement is ok.
ENDIF.
you alse can use:
FM: VIEW_MAINTENANCE_CALL can used to do table maintenance.
note:
1.to do Table Maintenance Generator.
2.be authorized to to use tansaction sm30.
好运,
启明星 -
Need help on the update statement
Hi,
I have a small requirement. I have a table called test1 and it has 2 columns, nam and seq. nam is a VARCHAR2(100) and seq is a NUMBER.
In the seq I have values like, 2, 3, 7, 9, 25. I would like to update the seq value in an order such that it will be modifed like, 1, 2, 3, 4 and 5.
Here is the scripts, I have used.
CREATE TABLE test1
(nam VARCHAR2(100),
seq NUMBER);
INSERT INTO test1 VALUES('AAA', 2);
INSERT INTO test1 VALUES('BBB', 3);
INSERT INTO test1 VALUES('CCC', 7);
INSERT INTO test1 VALUES('DDD', 9);
INSERT INTO test1 VALUES('EEE', 25);
COMMIT;
And, I would like to achive this in a simple single DML statement. (The required output would be something like, AAA - 1, BBB - 2 etc,...)
I have tried the following query. It is working fine. But If I have a better solution to it, I would to implement the same.
UPDATE test1 a
SET seq =
(SELECT rn
FROM (SELECT ROW_NUMBER() OVER(ORDER BY seq) rn FROM test1) x
WHERE a.rowid = x.rowid);
PS: I am using Oracle 11.2.0.2.0 (11g)
Thanks In Advance!
With Regards,
VSTSQL> CREATE TABLE test1
2 (nam VARCHAR2(100),
3 seq NUMBER);
Table created.
SQL> INSERT INTO test1 VALUES('AAA', 2);
1 row created.
SQL> INSERT INTO test1 VALUES('BBB', 3);
1 row created.
SQL> INSERT INTO test1 VALUES('CCC', 7);
1 row created.
SQL> INSERT INTO test1 VALUES('DDD', 9);
1 row created.
SQL> INSERT INTO test1 VALUES('EEE', 25);
1 row created.
SQL> COMMIT;
Commit complete.
SQL> select * from test1;
NAM SEQ
AAA 2
BBB 3
CCC 7
DDD 9
EEE 25
5 rows selected.
SQL> update test1 set seq = rownum;
5 rows updated.
SQL> select * from test1;
NAM SEQ
AAA 1
BBB 2
CCC 3
DDD 4
EEE 5
5 rows selected. -
CalcScript. Need help tunning this up, please
I have the following:
FIX ("mbrDim1",@RELATIVE("dim2",0), "mbrDim3", @RELATIVE("dim4",-1), "mbrDim5")
DATACOPY "No_mbrDim_6_"->"AUX_mbr*1*Dim_7_" TO "No_mbrDim_7_"->"mbr*1*Dim_6_";
DATACOPY "No_mbrDim_6_"->"AUX_mbr*2*Dim_7_" TO "No_mbrDim_7_"->"mbr*2*Dim_6_";
DATACOPY "No_mbrDim_6_"->"AUX_mbr*3*Dim_7_" TO "No_mbrDim_7_"->"mbr*3*Dim_6_";
DATACOPY "No_mbrDim_6_"->"AUX_mbr*4*Dim_7_" TO "No_mbrDim_7_"->"mbr*4*Dim_6_";
This is: Provided the foreseen FIX statement, I need to copy data from the "No_mbrDim6"->"AUX_mbr*Dim7" to the "No_mbrDim7"->"mbr*Dim6", so the AUX_ members on dim7 have to find their correspondent in dim6. There are technical reasons for this outline arrangement.
I've tried the following:
"No_mbrDim7" = "No_mbrDim6" -> @MEMBER(@SUBSTRING(@NAME(@CURRMBR("dim7Name")),4)); >>>> +Error: 1200370 Error executing formula for [No_mbrDim7] (line 0): attempt to cross a null member in function [@X]+
"No_mbrDim7" = "No_mbrDim6" -> @MEMBER(@SUBSTRING(@NAME(@RELATIVE("ParentMbr_AUX_mbrDim7",0)),4)); >>>> +Error: 1200497 Error compiling formula for [No_mbrDim7] (line 93): unknown member name ["ParentMbr_AUX_mbrDim7"] in function [@RELATIVE].+
(In both cases, the 4 is intended to remove the AUX_ prefix so member names in both dim6 and dim7 dimensions match).
As you can guess, even if the first option is bomb-proof, it's not a good option since the AUX_mbr*Dim7 and mbr*Dim6 members could vary oftenly.
Any ideas, please?
Many thanks!
Edited by: 836559 on Feb 14, 2011 8:18 AMHi,
If your refering like running the recovery you may check this thread for details -- >
http://laptopforums.toshiba.com/tshb/board/message?message.uid=683#U683
"I'm Not the Message... Just the Messenger.. i Don't Play the Music... The music plays through me... Im just a Channel..... That's all I AM " -
Immediate help required with this update statement
update holds set area = (select newarea from stagesteps)
where holds.stage= stagesteps.stagename and holds.step = stagesteps.STEPNAME and holds.area is not null
When I do this, it says stagesteps.stepame is an invalid name..
Any helps on this highly appreciated.. btw Advance thanx for your help.update holds h
set area = (select ss.newarea
from stagesteps ss
where ss.stagename = h.stage
and ss.stepname = h.step)
where area is not null
and exists (select null
from ss.newarea
from stagesteps ss
where ss.stagename = h.stage
and ss.stepname = h.step);You can leave off the EXISTS clause if there will be a guaranteed matching row in stagesteps for each row in holds, or if you don't care if area is set to null if there is no match. -
What classes do I need to make this "if" statement?
what classes do I use or how do write code that basically says:
if ( the key typed was not enter) {
I couldn't figure it out using the keylistener.
Thanks in advance.Use a KeyListener like this:
JTextField textField = new JTextField();
textField.addKeyListener(new KeyListener() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER)
System.out.println("Enter pressed");
@Override
public void keyReleased(KeyEvent e) {
@Override
public void keyTyped(KeyEvent e) {
});in keyPressed() and keyReleased() you can check for e.getKeyCode() == KeyEvent.VK_ENTER
in keyTyped() you should check for e.getKeyChar() == '\n' -
I need help with this while() statement please!
So I'm pretty new to Java programming and I cannot seem to understand why this is not looping if the user inputs a "n" at the end.
Here is my code:
* proj1nrh.java
* Created on September 28, 2007, 2:42 PM
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
package proj1nrh;
* @author Nate
import java.util.Scanner;
public class proj1nrh {
/** Creates a new instance of proj1nrh */
public proj1nrh() {
public static void main(String[] args) {
String areYouFinished;
char repeat;
Scanner keyboard = new Scanner (System.in);
int numericResponse1,
numericResponse2,
numericResponse3,
numericResponse4,
numericResponse5,
numericResponse6,
numericResponse7;
System.out.println("Survey #1");
System.out.println("Please enther the numerical student responses (1-5) for each question:");
System.out.println("Q1. The instructor was available for consultation.");
numericResponse1 = keyboard.nextInt ();
System.out.println("Q2. Student responsibilities for this course were well defined.");
numericResponse2 = keyboard.nextInt ();
System.out.println("Q3. Class time well spent.");
numericResponse3 = keyboard.nextInt ();
System.out.println("Q4. I learned a lot from the intructor in this course.");
numericResponse4 = keyboard.nextInt ();
System.out.println("Q5. Course material contributed to my learning.");
numericResponse5 = keyboard.nextInt ();
System.out.println("Q6. I was challenged in this course.");
numericResponse6 = keyboard.nextInt ();
System.out.println("Q7. Coming into this course, I was motivated to learn this subject.");
numericResponse7 = keyboard.nextInt ();
//Consume new line
keyboard.nextLine();
System.out.println("Are you finished (y/n)?");
areYouFinished = keyboard.nextLine();
repeat = areYouFinished.charAt(0);
} while (repeat == 'n' || repeat == 'N');
Thanks for the help!Ight you guys have been great help.... but I'm having another problem
* proj1nrh.java
* Created on September 28, 2007, 2:42 PM
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
package proj1nrh;
* @author Nate
import com.sun.xml.internal.bind.v2.schemagen.xmlschema.List;
import java.util.Scanner;
import java.util.ArrayList;
public class proj1nrh {
/** Creates a new instance of proj1nrh */
public proj1nrh() {
public static void main(String[] args) {
String areYouFinished;
char repeat;
int n = 0;
Scanner keyboard = new Scanner (System.in);
int numericResponse1, sumOfResponse1,
numericResponse2, sumOfResponse2,
numericResponse3, sumOfResponse3,
numericResponse4, sumOfResponse4,
numericResponse5, sumOfResponse5,
numericResponse6, sumOfResponse6,
numericResponse7, sumOfResponse7;
ArrayList storeValue1 = new ArrayList ();
ArrayList storeValue2 = new ArrayList ();
ArrayList storeValue3 = new ArrayList ();
ArrayList storeValue4 = new ArrayList ();
ArrayList storeValue5 = new ArrayList ();
ArrayList storeValue6 = new ArrayList ();
ArrayList storeValue7 = new ArrayList ();
do {
n = n + 1;
System.out.println("Survey #1");
System.out.println("Please enther the numerical student responses (1-5) for each question:");
System.out.println("Q1. The instructor was available for consultation.");
numericResponse1 = keyboard.nextInt ();
storeValue1.add(numericResponse1);
System.out.println("Q2. Student responsibilities for this course were well defined.");
numericResponse2 = keyboard.nextInt ();
storeValue2.add(numericResponse2);
System.out.println("Q3. Class time well spent.");
numericResponse3 = keyboard.nextInt ();
storeValue3.add(numericResponse3);
System.out.println("Q4. I learned a lot from the intructor in this course.");
numericResponse4 = keyboard.nextInt ();
storeValue4.add(numericResponse4);
System.out.println("Q5. Course material contributed to my learning.");
numericResponse5 = keyboard.nextInt ();
storeValue5.add(numericResponse5);
System.out.println("Q6. I was challenged in this course.");
numericResponse6 = keyboard.nextInt ();
storeValue6.add(numericResponse6);
System.out.println("Q7. Coming into this course, I was motivated to learn this subject.");
numericResponse7 = keyboard.nextInt ();
storeValue7.add(numericResponse7);
//Consume new line
keyboard.nextLine();
System.out.println("Are you finished (y/n)?");
areYouFinished = keyboard.nextLine();
repeat = areYouFinished.charAt(0);
} while (repeat == 'n' || repeat == 'N');
int sum = 0;
}I want to get the sum of each ArrayList 1-7 so I can divide this sum by "n" and display the average output.
Thanks! -
Need help with this CASE statement
Hi everyone,
I would like to create a CASE that references another view and uses fields in that view to create a new field in a new view.
The fields I am working with are called LEVEL_CD and AVAILABLE_AMT.
In this case I would like to create a field called AVAILABLE_AMT (in my new view) that inserts the AVAILABLE_AMT from the old view into the new field only if the LEVEL_CD = 1. If the LEVEL_CD is anything else but 1 I would like to insert a 0 into my new
AVAILABLE AMOUNT field.
This is what I have so far and it doesn't seem to work:
CASE WHEN old_view.LEVEL_CD = 1 THEN old_view.AVAILABLE_AMT
WHEN old_view.LEVEL_CD <> 1 THEN 0 END AS AVAILABLE_AMT
This just gives me zeroes in every record. Can anybody spot what I am doing wrong?
Thanks!SELECT <columns>,CASE WHEN old_view.LEVEL_CD
=
1
THEN old_view.AVAILABLE_AMT
ELSE 0 END AS AVAILABLE_AMTFROM old_view.PK JOIN new_view.PK WHERE....PS.PK -Primary Key
Best Regards,Uri Dimant SQL Server MVP,
http://sqlblog.com/blogs/uri_dimant/
MS SQL optimization: MS SQL Development and Optimization
MS SQL Consulting:
Large scale of database and data cleansing
Remote DBA Services:
Improves MS SQL Database Performance
SQL Server Integration Services:
Business Intelligence
Maybe you are looking for
-
Ichat times out when trying to sign in
I am in Europe for the year and haven't been able to get my ichat to sign on in my new apartment. I am not good with computers and do not know where to begin with trouble shooting this problem. I have done a lot of reading on sign in problems, but I
-
Help with Database Connected LiveCycle ES4 form
Hello and thanks for taking the time to read this question, I hope you can help! I have a LiveCycle ES 4 form connected to an excel database. The form has buttons to "Add", "Update" or "Find" a record. These buttons all work correctly EXCEPT when t
-
Weblogic.jndi.WLContext
Hello, I have this line in my code: import weblogic.jndi.WLContext; But when I compile it, I got the following error message: Class weblogic.jndi.WLContext not found in import. I think it's because I didn't set my CLASSPATH correctly. Am I right? Wha
-
I need to create project rooms that must be closed when the projects ends but their information must remain available. I tried locking the room but when it's locked users cannot enter it anymore. Is there a way to prevent user to create new events in
-
Our lead architect would like for OIM to use our corporate SOA cluster instead of the server that is installed with OIM 11g. I don't remember much about the OIM install to know if this is even an option. Anyway, what do you guys think? Good idea or n