簡體   English   中英

在Self上使用IN子查詢優化Update查詢

[英]Optimize an Update query using IN subquery on Self

我有一個80000行數據庫,結果編號在130000000和168000000之間,結果使用字段pid配對。 我需要將行的狀態從“ G”更改為“ X”,結果對之間的差值為4300000。

我想出了下面的查詢,該查詢可以運行,但是速度很慢,可以提高速度嗎?

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
);

索引是:-

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

在MySQL中,在IN(..)子句中使用子查詢通常效率不高。 相反,您可以使用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'

為了獲得良好的性能(如果我正確理解NLJ(嵌套循環連接) ),則需要兩個索引: (status,result)(pid)

第一個(復合)索引將用於考慮表別名a行。 由於我們對result具有范圍條件, result最好先定義status ,否則,由於范圍條件,MySQL只會在索引的result字段(如果先定義)處停止。

使用NLJ算法 ,第二個索引將用於Joined表別名b中的查找。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM