MySQL索引和鎖

2022-07-26 19:51:14 字數 1139 閱讀 7810

索引和鎖可以讓查詢鎖定更少的行。如果你的查詢從不訪問那些不需要訪問的行,那麼就會鎖定更少的行,從兩個方面來看這對效能都有好處。首先,雖然innodb的行鎖效率很高,記憶體使用也很少,但是鎖定行的時候仍然會帶來額外的開銷,其次,鎖定超過需要的行會增加鎖競爭,並減少併發性。

innodb只有在訪問行的時候才會對其加鎖,而索引能夠減少innodb訪問的行數,從而減少鎖的數量。但只有當innodb在儲存引擎能夠過濾掉不需要的行時才有效。如果索引無法過濾掉無效的行,那麼在innodb檢索到資料並返回給伺服器層以後,mysql伺服器才能應用where子句。這時候,已經無法避免鎖定行了:inno代表可以在伺服器端過濾掉行後就釋放鎖,但是在早期的mysql版本中,innodb只有在事務提交後才能釋放鎖。

通過下面的例子,很好的解釋了這些情況

select actor_id from actor where actor_id < 5 and actor_id<>1 for update;

這些表僅僅會返回2-4之間的行,但是實際上獲取了1-4之間行的排他鎖,innodb會鎖住第一行,這是因為mysql為該查詢選擇執行計畫是索引範圍掃瞄;換句話說,底層儲存引擎操作的是「從索引的開頭開始獲取滿足條件的actor_id<5的記錄」伺服器並沒有告訴innodb可以過濾掉第一行的where條件。注意到explain的extra列出現了「using where 」 這表示mysql伺服器將儲存引擎返回行以後再應用where過濾條件。

下面的第二個查詢就可以證明第一行確實已經被鎖定,儘管第乙個查詢的結果中並沒有這個第一行。保持第乙個連線開啟,然後開啟第二個連線並執行如下語句:

select actor_id from actor where actor_id = 1 for update.

這個查詢就會被掛起,直到第乙個事務釋放第一行的鎖。這個行為對於基於語句的複製的正常執行來說是必要的。

就像這個例子顯示的,即使使用了索引,innodb可能也會鎖住一些不需要的資料。如果不能使用索引查詢和鎖定行的話問題可能會很糟糕,mysql會做全表掃瞄並鎖定所有的行,而不管是不是需要。

關於innodb,索引和鎖有一些很少有人知道的細節:innodb在二級索引上使用共享鎖(讀鎖),但訪問主鍵索引需要排他鎖(寫),這消除了使用覆蓋索引的可能性,並且使得select for update 比lock in share mode  或非鎖定查詢要慢得多。

mysql鎖和索引關係

在平時我們用mysql的鎖時,一般剛接觸資料庫是很少考慮鎖的效率,一般只求到達防止併發的目的就可以了,但是隨著資料量的增大我們就會發現有很多sql我們已經寫的非常優化了,但是有時候還是很慢,很難找到原因,這時候我們就應該考慮一下是不是mysql的鎖在導致的。我們首先建立乙個新的資料表 這裡我們的主鍵...

mysql suoyin 和鎖 MySQL索引與鎖

每個資料頁裡面的記錄可以組成乙個單向鍊錶。在沒有任何索引的的表中,select語句的執行會進行如下兩次遍歷遍歷雙向鍊錶,找到所在頁 遍歷頁內的單鏈表,找到所在的記錄 索引提高檢索速度 索引的主要作用就是將無序變成有序。record type 1 代表存放的是普通目錄項的記錄 record type ...

mysql suoyin 和鎖 Mysql索引與鎖

mysql索引與鎖 mysql索引與鎖 本文以mysql5.7為例測試。1 mysql索引方法 mysql的索引方法分為btree索引和hash索引。hash索引 是通過hash計算後比較,所以只能用於等值過濾,不能用於範圍過濾。hash索引會根據列資料維護一張hash表,所以任何時候都要進行has...