update未走索引導致全表鎖住


事件經過:
前段時間, 自動化測試的小姐姐向我們開發人員反應, 由於我方經常debug導致鎖表, 她們的用例經常失敗.
該問題出現的時機基本一致,通過show OPEN TABLES where In_use > 0;以及show processlist, 確定sql.
但是奇怪的是這次的事故竟然是把整個表鎖了, 而不是以往只是某條數據被鎖住(開發和測試未單獨分庫, 調試時的某些數據偶爾會導致鎖表情況).
對sql進行分析后發現, 這條update后面的where竟然沒有走索引!!!

原因:
我們使用mysql時一般使用的都是默認引擎innoDB.
而innoDB的行鎖是通過給索引上的索引項枷鎖來實現的, 而不是針對記錄來加鎖的.
假如在操作數據的時候, 沒有索引, 是無法使用行級鎖的, 此時使用的是表鎖. (小伙伴們這下明白對mysql來說索引多重要了吧)

引申
同時引申一個有趣的現象. 假如多個線程操作的是不同數據, 也用了索引, 但是為什么還是鎖表了呢?
原因還是上面這個, 行鎖是在索引上的. 假如你where條件后面分別是: code=“001” and name=“xx” 和code=“001” and name=“yy”, 索引在code上, 那么還是會出現鎖表的.
例如:
tdb_goods 表中brand_name上有索引, 而goods_price字段無索引

在線程A中執行
START TRANSACTION;
UPDATE tdb_goods SET is_show=1 WHERE brand_name='蘋果' AND goods_price='3388.000';
然后在A執行COMMIT;之前在另一個線程B中開啟一個事務並執行UPDATE tdb_goods SET is_show=1 WHERE brand_name='蘋果' AND goods_price='2288.000';
此時線程Bmysql會提示:
錯誤代碼: 1205
Lock wait timeout exceeded; try restarting transaction
1
2
3
4
5
6
7
那么
另外需要注意一點: 如果表比較小, 即使有索引, mysql也不一定會走索引而是查全表.
————————————————
版權聲明:本文為CSDN博主「yytoo2」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/yytoo2/article/details/107557246


免責聲明!

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



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