[英]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. 我有一个80000行数据库,结果编号在130000000和168000000之间,结果使用字段pid配对。 I need to change the status of the rows from 'G' to 'X' where the result pair has a difference of 4300000. 我需要将行的状态从“ G”更改为“ X”,结果对之间的差值为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. 在MySQL中,在IN(..)
子句中使用子查询通常效率不高。 Instead, you can rewrite the Update query utilizing UPDATE .. JOIN
syntax and utilize "self-join" as well: 相反,您可以使用UPDATE .. JOIN
语法重写Update查询,也可以使用“自我UPDATE .. JOIN
”:
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)
. 为了获得良好的性能(如果我正确理解NLJ(嵌套循环连接) ),则需要两个索引: (status,result)
和(pid)
。
First (composite) index will be used to consider rows from the table alias a
. 第一个(复合)索引将用于考虑表别名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. 由于我们对result
具有范围条件, result
最好先定义status
,否则,由于范围条件,MySQL只会在索引的result
字段(如果先定义)处停止。
Second index will be used for lookups in the Joined table alias b
, using NLJ algorithm . 使用NLJ算法 ,第二个索引将用于Joined表别名b
中的查找。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.