tags:

views:

47

answers:

3

In MySQL,

update table1 t1 
   set column1 = 100,
       column2 = 200
 where column3 > 500 
   and not exists(select * 
                    from table2 
                   where column1 = t1.column1);

This query is too time consuming to execute, do have any other faster way of rewriting.

for table2 ID is a primary column so i guess i can rewrite as

update table1 t1 
   set column1 = 100,
       column2 = 200
 where column3 > 500 
   and not exists(select ID 
                   from table2  
                  where column1 = t1.column1);

but still the query takes 2 secs to run, i want something in millisecs.

A: 

When using Not exists, as soon as the query processor finds a row, it can stop, but if the row truly does not exist, then it has to examine the entire table (for the columns defined in the subquery) before it knows for sure that the row does not exist... So the only way to speed it up is, if there are any filters in the subquery, to place an index or indices on those columns. In your case, that would mean an index on Table2.column1

Using a join instead is likely to not be a help, because whether it is a join or a not exists subquery, the query processor has to perform the same logical IOs to process the data.

To use a join, (i'm not sure about MySql syntax, it might be:P

UPDATE TABLE1 SET
     column1 = 100, 
     column2 = 200 
  From Table1 t1
      Left Join TABLE2 t2 
          ON t2.column1 = t1.column1 
  WHERE t2.column1 Is Null

or

  Update t1 Set
     column1 = 100, 
     column2 = 200 
  From Table1 t1
      Left Join Table2 t2 
          ON t2.column1 = t1.column1 
  Where t2.column1 Is Null
Charles Bretana
Thanks, can you help me how can i put the above query in join, am not able to get it right. So you mean to say that outer join will bring down the time consuming.
Sharpeye500
Added sql for joins, but I'm not familiar with mysql syntax, so these may not be exactly correct...
Charles Bretana
+2  A: 

Try this (which does not use a correlated sub-query):

UPDATE Table1
   SET Column1 = 100, Column2 = 100
 WHERE Column3 > 500
   AND Column1 NOT IN (SELECT Column1 FROM Table2);
Jonathan Leffler
+2  A: 

Try this instead:

   UPDATE TABLE1 
LEFT JOIN TABLE2 ON TABLE2.column1 = TABLE1.column1
                AND TABLE2.column2 IS NULL 
      SET column1 = 100,
          column2 = 200
    WHERE TABLE2.column1 IS NULL
      AND column3 > 500 
OMG Ponies
Thanks OMG Ponies. I am close , actually i missed this condition in the not exists statement and not exists(select ID from table2 where column1=t1.column1 and column2 is null); I need to add this, else its updating all the records.
Sharpeye500
@OMG Ponies - Thanks, but this is my query upate table1 t1 set column1=100,column2=200where column3>500 and not exists(select * from table2 where column1=t1.column1 and column2 is null); Does the above one take care of not exists?
Sharpeye500
@Sharpeye500: I missed the column3 comparison - corrected. Otherwise, the NOT IN, NOT EXISTS, and LEFT JOIN / IS NULL are equivalent -- only difference is LEFT JOIN / IS NULL is more efficient on MySQL if the column(s) compared can not be null (IE: column1). Otherwise, NOT IN or NOT EXIST perform better.
OMG Ponies
Thanks, the update for the first table should happen for the records that are not retrieved from this statement."select * from table2 where column1=t1.column1 and column2 is null". In the above case where do you tell these records are not considered, i guess you are joining both , sorry if am overbearing, can you pls. tell me how you convert the not in into join preserving the same functionality.
Sharpeye500
@Sharpeye500: This part: `WHERE TABLE2.column1 IS NULL` is what's responsible for filter out unwanted records - if there's no match in the LEFT JOIN, then the TABLE2 column values will be NULL. So you use that in the WHERE clause to get rid of the rows that match on the JOIN criteria.
OMG Ponies