在mysql中,使用update join時(shí),帶有order by會(huì)導(dǎo)致mysql崩潰嗎?
在mysql中,不能在帶有join的update語(yǔ)句中使用order by。這會(huì)導(dǎo)致mysql內(nèi)部錯(cuò)誤,甚至導(dǎo)致mysql崩潰。
原因
當(dāng)update語(yǔ)句中包含join時(shí),mysql將執(zhí)行以下操作:
- 評(píng)估join條件,將匹配的記錄分組。
- 對(duì)于每個(gè)匹配的組,執(zhí)行update操作。
order by子句用于對(duì)結(jié)果集進(jìn)行排序。但是,在帶有join的update語(yǔ)句中,order by無(wú)法保證哪個(gè)組將首先被更新。這可能會(huì)導(dǎo)致mysql內(nèi)部錯(cuò)誤或崩潰。
修復(fù)方法
為了修復(fù)此問(wèn)題,必須使用子查詢或臨時(shí)表來(lái)對(duì)記錄進(jìn)行排序:
使用子查詢:
update cfg_dev_network_push_status t1 set ... where (t1.id, t1.push_status, t1.push_retry_times) in ( select id, push_status, push_retry_times from ( select id, push_status, push_retry_times from cfg_dev_network_push_status join cfg_dev_network_bind_status on ... order by push_status desc, push_retry_times desc, id asc ) as subquery );
登錄后復(fù)制
使用臨時(shí)表:
CREATE TEMPORARY TABLE tmp_sort AS SELECT id, push_status, push_retry_times FROM cfg_dev_network_push_status JOIN cfg_dev_network_bind_status ON ... ORDER BY push_status DESC, push_retry_times DESC, id ASC; UPDATE cfg_dev_network_push_status t1 SET ... WHERE (t1.id, t1.push_status, t1.push_retry_times) IN ( SELECT id, push_status, push_retry_times FROM tmp_sort );
登錄后復(fù)制