MySQL 支援多種跨表更新語法,效能差異巨大。本文從基礎寫法到 JOIN 優化,透過實例對比展示最高效的跨表 UPDATE 實作模式。
UPDATE student s, city c SET s.city_name = c.name WHERE s.city_code = c.code;
UPDATE a, b SET a.title = b.title, a.name = b.name WHERE a.id = b.id;
UPDATE student s SET city_name = (SELECT name FROM city WHERE code = s.city_code);
UPDATE t_advs_order
SET attribute1 = (SELECT o.order_state FROM tk_zyt_scenery_order o WHERE o.order_id = `on`),
attribute2 = (SELECT o.order_state FROM tk_zyt_scenery_order o WHERE o.order_id = `on`)
WHERE EXISTS (SELECT 1 FROM tk_zyt_scenery_order o WHERE o.order_id = `on`);
問題: 三次掃描同一張表,隨資料量增長效能指數級下降。
UPDATE t_advs_order a INNER JOIN tk_zyt_scenery_order s ON s.order_id = a.`on` SET a.attribute1 = s.order_id, a.attribute2 = s.order_id;
優勢: 單次 JOIN 完成多欄更新,利用索引關聯,效能提升數十倍。
UPDATE t1 LEFT JOIN t2 ON t1.id = t2.t1_id SET t1.col = COALESCE(t2.value, 'default');
UPDATE t1 JOIN t2 ON t1.id = t2.t1_id JOIN t3 ON t2.id = t3.t2_id SET t1.status = t3.final_status WHERE t1.type = 'order';
UPDATE orders o
JOIN customers c ON o.cust_id = c.id
SET o.discount = CASE
WHEN c.vip_level = 3 THEN 0.8
WHEN c.vip_level = 2 THEN 0.9
ELSE 1.0
END;
WITH updated AS (
SELECT o.id, c.new_status
FROM orders o
JOIN customers c ON o.cust_id = c.id
WHERE o.status = 'pending'
)
UPDATE orders o
JOIN updated u ON o.id = u.id
SET o.status = u.new_status;