简体   繁体   中英

Optimize an Update query using IN subquery on Self

I have a 80000 row database with a result number between 130000000 and 168000000, the results are paired using field pid. I need to change the status of the rows from 'G' to 'X' where the result pair has a difference of 4300000.

I have come up with the query below, which works but is very slow, can it be improved for speed?

UPDATE table1 SET status = 'X'
WHERE id IN (
SELECT id FROM (
    SELECT a.id AS id FROM table1 a, table1 b
    WHERE a.result = b.result + 4300000
    AND a.pid = b.pid
    AND a.result between 130000000 and 168000000
    AND a.status = 'G'
    ) AS c
);

The indexes are:-

table1  0   PRIMARY 1   id  A   80233   NULL    NULL        BTREE
table1  1   id  1       id  A   80233   NULL    NULL        BTREE
table1  1   id  2   result  A   80233   NULL    NULL        BTREE
table1  1   id  3   status  A   80233   4   NULL    YES BTREE
table1  1   id  4   name    A   80233   32  NULL        BTREE
table1  1   id  5    pid    A   80233   16  NULL        BTREE

Using a subquery inside the IN(..) clause is generally inefficient in MySQL. Instead, you can rewrite the Update query utilizing UPDATE .. JOIN syntax and utilize "self-join" as well:

UPDATE table1 AS a 
JOIN table1 AS b 
  ON b.pid = a.pid 
     AND b.result = a.result - 4300000 
SET a.status = 'X'
WHERE a.result between 130000000 and 168000000 
  AND a.status = 'G'

For good performance (and if I understand NLJ (Nested-Loop-Join) correctly), you would need two indexes: (status,result) and (pid) .

First (composite) index will be used to consider rows from the table alias a . Since we have range condition on result , it will be better to define status first, otherwise MySQL would simply stop at the result field in the index (if defined first), due to range condition.

Second index will be used for lookups in the Joined table alias b , using NLJ algorithm .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM