Without a row source plan it is still not easy to know which is the most time and energy consuming operations in the plan Nevertheless, I would have tried to add a virtual column so that it will be easy to exclude, from the update, rows that have not null mycolumn (which I have supposed below to be of number datatype): alter table mytable add my_null_col number generated always as (case when mycolumn is null then -1 else null end) virtual; create index ind_virt on mytable (my_null_col); update mytable a set a.mycolumn = (select b.mycolumn from mytable b where a.joincolumn = b.joincolumn and b.anothercol ='someval') where a.my_null_col = -1; Best Regards Mohamed Houri www.hourim.wordpress.com 2014-02-26 8:17 GMT+01:00 Jonathan Lewis <jonathan@xxxxxxxxxxxxxxxxxx>: > > > > Look at the access path into the subquery table - it's using an index on > "anothercol" which is deemed to be very expensive, and then visiting the > table to check "joincolumn" to limit the result set to a single row. > It looks as if you don't have a suitable index into mytable to make this > subquery approach efficient. > > Two possible strategies - use a hash join (either through a MERGE > command or by using an UPDATEABLE JOIN VIEW, if you have suitable > constraints in place) or create an index that starts with joincolumn and > anothercol in some order to avoid visiting the subquery table (or an index > on joincolumn, perhaps, to minimise visits to the subquery table) > > > Regards > Jonathan Lewis > http://jonathanlewis.wordpress.com > @jloracle > ------------------------------ > *From:* oracle-l-bounce@xxxxxxxxxxxxx [oracle-l-bounce@xxxxxxxxxxxxx] on > behalf of Praveen Ramanan [pramanan@xxxxxxxxx] > *Sent:* 26 February 2014 04:00 > > *To:* oracle-l@xxxxxxxxxxxxx > *Subject:* Update statement performance > > Hello All, > > I am using oracle 11gr2 on windows server 2008. > This is a test system.Stats are current and archivelog is turned off > temporarily. > > I am trying to update a table that has over 1.1 million rows. > I have a simple update statement that does the following. (basically > updates mycolumn when it is null, to somevalue) > > update mytable a set a.mycolumn = (select b.mycolumn from > mytable > b where > > a.joincolumn = b.joincolumn and > > b.anothercol='someval') > where a.mycolumn is null; > > The number of rows where mycolumn is null is around 1/5th of the total. > (225000 rows) > > The above update statement seems to be running forever.On checking the > explain plan this is what i see. > > > > > --------------------------------------------------------------------------------------------------------- > | Id | Operation | Name | Rows | > Bytes | Cost (%CPU)| Time | > > --------------------------------------------------------------------------------------------------------- > | 0 | UPDATE STATEMENT | | 224K| > 2630K| 6454M (1)|127:19:43 | > | 1 | UPDATE | mytable | | > | | | > |* 2 | TABLE ACCESS FULL |mytable | 224K| > 2630K| 6644 (1)| 00:00:01 | > |* 3 | TABLE ACCESS BY INDEX ROWID| mytable | 1 | 21 | > 28752 (1)| 00:00:03 | > |* 4 | INDEX RANGE SCAN | mytable_someval_INDEX | > 874K| | 3318 (1)| 00:00:01 | > > --------------------------------------------------------------------------------------------------------- > > Predicate Information (identified by operation id): > --------------------------------------------------- > > 2 - filter("a"."mycolumn" IS NULL) > 3 - filter("b"."joincolumn"=:B1) > 4 - access("b"."anothercol"='somecol') > > > I know i can use CTAS to achieve my task.However i am not sure why > updating a .225 million rows would take hours. > > Can my update statement be written more efficiently? (perhaps using > merge update?) > > Maybe there is some other bottleneck that I need to look? > > Any thoughts would be very well appreciated. Thanks!!! > > > > > > > -- > *Thousands of candles can be lighted from a single candle, and the life > of the single candle will not be shortened. Happiness never decreases by > being shared.* > -- Bien Respectueusement Mohamed Houri