首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 多表關聯 UPDATE:JOIN 更新兩表字段的標準寫法

     編輯:MySQL 綜合教學

業務常需「根據關聯表字段值更新本表字段」,MySQL 支持 UPDATE ... JOIN 標準語法,比子查詢更高效、語義更清晰。本文詳解語法、索引優化、事務一致性與避坑指南。

核心語法

-- 單表更新引用另一表列
UPDATE t1
INNER JOIN t2 ON t1.key_col = t2.key_col
SET t1.target_col = t2.src_col
[WHERE t1.filter_col = 'val'];

實戰示例

-- 場景:訂單表根據用戶表更新用戶真實姓名冗余字段
UPDATE orders o
INNER JOIN users u ON o.user_id = u.id
SET o.user_real_name = u.real_name
WHERE o.user_real_name IS NULL OR o.user_real_name != u.real_name;

多字段同時更新

UPDATE t1
INNER JOIN t2 ON t1.id = t2.t1_id
SET t1.col_a = t2.col_x,
    t1.col_b = t2.col_y,
    t1.updated_at = NOW();

LEFT JOIN 更新(允許關聯為空)

-- 若 t2 無匹配行,t1.col 置為默認值/NULL
UPDATE t1
LEFT JOIN t2 ON t1.key_col = t2.key_col
SET t1.target_col = COALESCE(t2.src_col, 'DEFAULT_VAL');

索引優化關鍵點

  1. 關聯列必須有索引:t1.key_col、t2.key_col 至少一方有索引,最好雙方都有
  2. WHERE 條件列加索引:減少掃描行數
  3. 避免類型隱式轉換:VARCHAR 關聯 INT 導致全表掃描
  4. EXPLAIN 驗證:type=ref/eq_ref、rows 小、Using where 合理

事務與一致性

START TRANSACTION;
UPDATE t1 JOIN t2 ON t1.id = t2.t1_id SET t1.col = t2.val WHERE t1.id = 100;
-- 同事務內其他操作
COMMIT;
  • InnoDB 行鎖鎖定 t1 修改行 + t2 讀取行(SELECT ... LOCK IN SHARE MODE 隱式)
  • 大批量更新拆分小事務,避免長鎖、Binlog 膨脹、主從延遲

常見坑點

坑點現象解決
子查詢寫法 SET col = (SELECT ...)子查詢返回多行報錯;無索引慢;無法多字段更新改用 UPDATE ... JOIN
關聯條件含 NULLNULL = NULL 為 UNKNOWN,不匹配用 COALESCE 或 IS NULL 額外條件
更新同表別名衝突UPDATE t1 JOIN t1 AS t2 ... 易混淆用清晰別名、加註釋
觸發器遞歸AFTER UPDATE 觸發器再更新同表 → 死循環觸發器內判斷 IF NEW.col <> OLD.col 或用標志位表

大表分批更新模板

-- 1. 先查出需更新的主鍵 ID 分批
CREATE TEMPORARY TABLE tmp_ids (id INT PRIMARY KEY);
INSERT INTO tmp_ids SELECT t1.id FROM t1 JOIN t2 ON t1.k = t2.k WHERE t1.col != t2.val LIMIT 5000;

-- 2. 循環更新
WHILE (SELECT COUNT(*) FROM tmp_ids) > 0 DO
  START TRANSACTION;
  UPDATE t1 JOIN tmp_ids USING (id) JOIN t2 ON t1.k = t2.k SET t1.col = t2.val;
  COMMIT;
  TRUNCATE tmp_ids;
  INSERT INTO tmp_ids SELECT t1.id FROM t1 JOIN t2 ON t1.k = t2.k WHERE t1.col != t2.val LIMIT 5000;
  DO SLEEP(0.1);
END WHILE;

總結

UPDATE ... JOIN 是 MySQL 多表更新的標準高效寫法。關鍵在於:關聯列建索引、WHERE 縮小範圍、分批提交事務、EXPLAIN 驗證執行計劃。避免子查詢、隱式轉換、觸發器遞歸等陷阱。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved