這一片海,源于那一瓢水

          Schema的優化和索引 - 高性能的索引策略 - 索引和鎖(轉)

          InnoDB中,索引所扮演的角色是非常重要的。因為它們可以能讓語句鎖定更少的行。這是個要考慮的事情,因為在MySQL5.0 InnoDB中一個事物提前之前,是不會釋放鎖的。

          如果查詢語句不會檢索它們不需要的行。它們將鎖定更少的行。并且對于性能有提高,原因有二:首先,即使InnoDB行鎖是非常有效率的并且使用更少的內存,但是行鎖也會消耗一定的資源。其次,鎖定很多的行就提高了鎖的競爭并且降低了并發。

          僅當InnoDB訪問行的時候,才對它們加鎖,并且一個索引可以降低InnoDB所要訪問的行,因此也會降低鎖。然而,這種情況只適用于在存儲引擎級別中,InnoDB過濾了不期望的行。如果索引不允許InnoDB那么做,MySQL服務器就會在InnoDB取到這些值并且返回服務層之后,應用WHERE條件了。這種情況下,避免行的鎖定就太晚了:InnoDB已經鎖定了它們,并且服務器是不可能解鎖的。

          為了更好的理解我們看個例子,我們還是用以前的數據庫Sakila

          mysql> SET AUTOCOMMIT=0;
          mysql> BEGIN;
          mysql> SELECT actor_id FROM sakila.actor WHERE actor_id < 5
              -> AND actor_id <> 1 FOR UPDATE;
          +----------+
          | actor_id |
          +----------+
          |        2 |
          |        3 |
          |        4 |
          +----------+

          這個查詢返回了2到4行,但是實際上它已經獲得了1到4行的獨占鎖。InnoDB鎖定了第一行,因為這個語句是個索引范圍讀取:

          mysql> EXPLAIN SELECT actor_id FROM sakila.actor
              -> WHERE actor_id < 5 AND actor_id <> 1 FOR UPDATE;
          +----+-------------+-------+-------+---------+--------------------------+
          | id | select_type | table | type  | key     | Extra                    |
          +----+-------------+-------+-------+---------+--------------------------+
          |  1 | SIMPLE      | actor | range | PRIMARY | Using where; Using index |
          +----+-------------+-------+-------+---------+--------------------------+

          換句話說,這個低級別的存儲引擎操作是“從索引開始并且獲取所有的行直到actor_id<5為false”。服務器是不會告訴InnoDB,WHERE actor_id <>1的條件。來看下EXTRA列的Using where。這就說明了在存儲引擎返回行之后,MySQL服務器用WHERE進行了過濾。

          下面的語句證明了第一行已經被鎖了,即使它不會出現在第一個查詢結果之中。丟掉第一個連接,開始第二個連接執行下列語句。

          mysql> SET AUTOCOMMIT=0;
          mysql> BEGIN;
          mysql> SELECT actor_id FROM sakila.actor WHERE actor_id = 1 FOR UPDATE;

          這個查詢會被掛起。等待第一個事物是否第一行的鎖。這個行為是為了保證基于語句級的復制是正確的。(在復制的一節會說道。)

          就像這個例子所顯示的,即使使用了索引,InnoDB還回會鎖定它并不是真正需要的行。當不使用索引去查找和鎖定行,這樣的問題會更嚴重:如果這個語句沒有索引,不管需不需要,MySQL都會掃描整張表并且鎖定每個行。

          下面談一下InnoDB,索引和鎖的一些鮮為人知的細節:InnoDB會把共享鎖放置在次要索引上,但是獨占鎖需要訪問主鍵。這就降低了使用覆蓋索引的可能性并且會導致SELECT FOR UPDATE 慢于LOCK IN SHARE MODE 或者沒有鎖的查詢。

          posted on 2010-06-25 17:54 何方 閱讀(170) 評論(0)  編輯  收藏 所屬分類: Stack

          My Links

          Blog Stats

          常用鏈接

          留言簿

          隨筆檔案

          文章分類

          文章檔案

          相冊

          搜索

          最新評論

          主站蜘蛛池模板: 军事| 巴塘县| 济宁市| 孝昌县| 平舆县| 莱西市| 太和县| 巨野县| 焦作市| 祁东县| 横山县| 万荣县| 肇州县| 阿图什市| 平定县| 乾安县| 射阳县| 察哈| 连山| 沙雅县| 叶城县| 宜都市| 友谊县| 高台县| 湖北省| 湘西| 华安县| 科技| 东安县| 乌什县| 锡林郭勒盟| 司法| 武穴市| 台南县| 清丰县| 南漳县| 巍山| 敦煌市| 岚皋县| 湄潭县| 融水|