Mysql

優化 MySQL 更新語句

  • February 25, 2019

我有一個更新查詢,它從表 (HST) 中選擇數據並將其更新到另一個表 (PCL) 中。PCL 表包含約 30000 行,而 HST 表包含約 110 萬行。我在 HST 上有多個(複合)索引,儘管它是一個大表,但所有查詢都相當快(~2-3 秒)。但是,當我嘗試從該表中選擇行並更新 PCL 時,需要 3-4 小時,並且在大多數情況下,我會收到“超過鎖定等待超時;嘗試重新啟動事務”錯誤,我必須繼續嘗試直到它起作用。

UPDATE PCL 
SET `T2A` = (SELECT HST.`Date` from `HST` WHERE HST.`SYM`=PCL.INST AND 
HST.`DATE` >=  PCL.Date AND HST.`HP` >= PCL.T2 order by HST.`Date` limit 1)    
WHERE `BS` = 'B' AND `T1A` IS NOT NULL; 

有沒有辦法可以重寫上面的查詢,使其執行得更快?

想想類似的東西

UPDATE PCL, ( SELECT PCL.SrNo, MIN(HST.Date) minDate
             FROM PCL, HST 
             WHERE HST.SYM=PCL.INST 
               AND HST.DATE >=  PCL.Date 
               AND HST.HP >= PCL.T2 
               AND PCL.BS = 'B' 
               AND PCL.T1A IS NOT NULL
             GROUP BY PCL.SrNo ) subquery
SET PCL.T2A = subquery.minDate
WHERE PCL.SrNo = subquery.SrNo;

當然,兩個表上的正確索引是安全的。

編寫此類查詢的另一種方法:

UPDATE PCL AS p
 JOIN HST AS h
   ON h.SrNo = 
      ( SELECT hi.SrNo
        FROM HST AS hi
        WHERE hi.SYM = p.INST
          AND hi.DATE >=  p.Date 
          AND hi.HP >= p.T2
        ORDER BY hi.Date 
        LIMIT 1 
      )    
SET p.T2A = h.Date 
WHERE p.BS = 'B'
 AND p.T1A IS NOT NULL ;

引用自:https://dba.stackexchange.com/questions/230458