InnoDB行鎖特色

InnoDB行鎖是經過給索引上的索引項加鎖來實現的,這一點MySQLORACLE不一樣,後者是經過在數據塊中對相應數據行加鎖來實現的。InnoDB這種行鎖實現特色意味着:只有經過索引條件檢索數據,InnoDB才使用行級鎖,不然,InnoDB將使用表鎖!mysql

在實際應用中,要特別注意InnoDB行鎖的這一特性,否則的話,可能致使大量的鎖衝突,從而影響併發性能。下面咱們經過一些實際例子,來加以說明。web

1)在不經過索引條件查詢的時候,InnoDB確實使用的是表鎖,而不是行鎖。sql

下面的例子中,開始tab_no_index表沒有索引:session

    mysql> create table tab_no_index(id int,name varchar(10)) engine=innodb;併發

    Query OK, 0 rows affected (0.15 sec)性能

    mysql> insert into tab_no_index values(1,'1'),(2,'2'),(3,'3'),(4,'4');spa

    Query OK, 4 rows affected (0.00 sec)orm

    Records: 4 Duplicates: 0 Warnings: 0索引

                     InnoDB存儲引擎的表在不使用索引時使用表鎖例子                   ci

session_1

session_2

mysql> set autocommit=0;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from tab_no_index where id = 1 ;

+------+------+

| id   | name |

+------+------+

| 1    | 1    |

+------+------+

1 row in set (0.00 sec)

mysql> set autocommit=0;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from tab_no_index where id = 2 ;

+------+------+

| id   | name |

+------+------+

| 2    | 2    |

+------+------+

1 row in set (0.00 sec)

mysql> select * from tab_no_index where id = 1 for update;

+------+------+

| id   | name |

+------+------+

| 1    | 1    |

+------+------+

1 row in set (0.00 sec)

mysql> select * from tab_no_index where id = 2 for update;

等待

上面的例子中,看起來session_1只給一行加了排他鎖,但session_2在請求其餘行的排他鎖時,卻出現了鎖等待!緣由就是在沒有索引的狀況下,InnoDB只能使用表鎖。當咱們給其增長一個索引後,InnoDB就只鎖定了符合條件的行,以下例所示:

建立tab_with_index表,id字段有普通索引

    mysql> create table tab_with_index(id int,name varchar(10)) engine=innodb;

    Query OK, 0 rows affected (0.15 sec)

    mysql> alter table tab_with_index add index id(id);

    Query OK, 4 rows affected (0.24 sec)

    Records: 4 Duplicates: 0 Warnings: 0

                                   InnoDB存儲引擎的表在使用索引時使用行鎖例子

session_1

session_2

mysql> set autocommit=0;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from tab_with_index where id = 1 ;

+------+------+

| id   | name |

+------+------+

| 1    | 1    |

+------+------+

1 row in set (0.00 sec)

mysql> set autocommit=0;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from tab_with_index where id = 2 ;

+------+------+

| id   | name |

+------+------+

| 2    | 2    |

+------+------+

1 row in set (0.00 sec)

mysql> select * from tab_with_index where id = 1 for update;

+------+------+

| id   | name |

+------+------+

| 1    | 1    |

+------+------+

1 row in set (0.00 sec)

mysql> select * from tab_with_index where id = 2 for update;

+------+------+

| id   | name |

+------+------+

| 2    | 2    |

+------+------+

1 row in set (0.00 sec)

相關文章
相關標籤/搜索