mysql優化 update中的in子句


需求:mysql數據庫中,更新所有message_repo表中所有state='100' and receiver_id = '1'的數據為state='100',表中id為主鍵,state和receiver_id都有索引。

原語句:

update message_repo set state = '101' , update_time = now() , read_time = now() where id in (select a.id from (select id from message_repo where state = '100' and receiver_id = '1') a);

然后發現,workbench提示處於安全模式,即safe mode下只能采用主鍵更新。

我的id不就是主鍵?難道這個還不是主鍵更新,意識到這個sql肯定被mysql錯誤理解了,用執行分析果然發現問題。。。

 

 update的where子句沒有使用主鍵索引,而是進行了全表掃描。

原本sql要表達的意思是:用select子句查詢所有符合條件的主鍵,然后update通過主鍵進行更新,但是實際上,mysql是全表逐行與select子句對比,沒有比這個更傻的操作了,要是表中數據多一點,死鎖是必定的。

更別說:這語句需要關閉safe mode。

 

優化后語句:

update message_repo a join (select id from message_repo where state = '100' and receiver_id = '1') b on a.id=b.id set state = '101' , update_time = now() , read_time = now();

通過join子句,明確告訴mysql,我要先用主鍵進行篩選。

執行計划

 

 這下就正常,從執行計划上看,所有條件都符合預期。

 

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM