Mysql索引与锁

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 本文以Mysql5.7为例测试。

1:mysql索引方法



Mysql的索引方法分为btree索引和hash索引。


hash索引:是通过hash计算后比较,所以只能用于等值过滤,不能用于范围过滤。Hash索引会根据列数据维护一张hash表,所以任何时候都要进行hash表扫描,当hash表数据量庞大时,性能急剧下降。


image.png

1.png


Btree索引:BTREE索引就是一种将索引值按一定的算法,存入一个树形的数据结构中。


2:组合索引


组合索引index1(c1,c2)


Sql语句 是否使用索引
select * from t1 where c1=1 and c2=2
select * from testindex where c2>'1' and c1<'2'
select * from t1 where c1=1
select * from t1 where c2=2 ×


结论:如果需要使用c2过滤时使用索引,必须同时用c1过滤


image.png

2.png


3:索引对锁的影响


Innodb存储引擎下,mysql锁是通过锁索引实现。


Mysql在innodb下默认是表级锁。可通过下面实例看出。


我们创建表testnoindex:

CREATE TABLE `testnoindex` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `c1` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;


Id为主键索引,c1为普通字段,初始化一些数据方便查看


image.png

3.png


开启两个事务窗口


Session1:设置不自动提交,并执行update语句,根据条件可以看出,更新的是id为10的记录,执行完如果没有显式调用commit,则会锁整个表。


SET AUTOCOMMIT=0;


update testnoindex set c1='2017-08-0209:52:21' where c1='2017-08-02 10:47:20';

注意:c1一定是无索引情况,如果有索引(非唯一索引),都不会锁整张表。


session2:更新id为1的记录,获取锁超时。


image.png

4.png


以上实例可以证明mysql innodb存储引擎默认是表级锁,当然innodb是支持行级锁的,比如通过唯一主键就可实现行级锁。


如果where条件的索引数据是多行的话,多行数据会同时被锁定,可理解为范围锁。

Mysql有三种锁Record,Gap, and Next-KeyLocks。Recode为行锁,Gap为间隙锁,Next-KeyLocks为前两种的结合。我们先看一个实例,加入mysql中记录为如下所示:


image.png

5.png


Session1:执行下面语句,因为没有7的记录,会向左扫描至id=2的记录,向右扫描至id=8的记录,锁定区间为(2,8)。

set autocommit=0;
update testnoindex set c1='2017-08-0210:47:09' where id=7;


session2:执行如下语句,可以看出id=4的记录被锁定。

INSERT into testnoindex (id,c1)values(16,NOW());
INSERT into testnoindex (id,c1)values(4,NOW());
[SQL]INSERT into testnoindex (id,c1)values(16,NOW());


受影响的行: 1


时间: 0.087s

[SQL]
INSERT into testnoindex (id,c1)values(4,NOW());
[Err] 1205 - Lock wait timeout exceeded;try restarting transaction


4:共享锁与排他锁


Mysql行级锁又分为共享锁(读锁或S锁)和排他锁(写锁或X锁),比如forupdate就是排它锁。Mysql默认delete,insert,update都是排它锁,select默认无锁。


²  如果行记录被加了排它锁,则其他事务无法再在其上加锁,也就是加锁状态无法读取/修改。换句话说就是如果被加了排他锁的行,不能再加排他或共享锁,但是可以无锁读取(普通select,)。


²  如果行记录被加了共享锁,则其他事务只能在共享锁或无锁状态下读取。


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
3天前
|
关系型数据库 MySQL 数据库
MySQL的行级锁锁的到底是什么?
本文简述了InnoDB的行级锁机制,包括记录锁、间隙锁和Next-Key锁。记录锁锁定索引记录,防止其他事务对相同值的行进行操作;间隙锁锁定索引记录间的间隙,防止插入。Next-Key锁是两者的结合,锁定记录及其前后间隙。在可重复读(RR)隔离级别下,加锁策略涉及Next-Key锁,但会因查询条件退化为行锁或间隙锁。MySQL的加锁机制遵循两个原则和两个优化,例如唯一索引等值查询时退化为行锁。RR级别虽能防止幻读,但也可能降低并发并引发死锁,因此有些场景下会选择读已提交(RC)级别。
MySQL的行级锁锁的到底是什么?
|
3天前
|
SQL 存储 关系型数据库
MySQL索引及事务
MySQL索引及事务
24 2
|
3天前
|
SQL 存储 关系型数据库
必知的 MySQL 索引失效场景【包括实践验证】,别再踩坑了!(下)
必知的 MySQL 索引失效场景【包括实践验证】,别再踩坑了!
22 2
|
3天前
|
SQL 关系型数据库 MySQL
必知的 MySQL 索引失效场景【包括实践验证】,别再踩坑了!(上)
必知的 MySQL 索引失效场景【包括实践验证】,别再踩坑了!
19 2
|
3天前
|
NoSQL 关系型数据库 MySQL
B+树 和 跳表 的结构及区别,不同的用途【mysql的索引为什么使用B+树而不使用跳表?】
B+树 和 跳表 的结构及区别,不同的用途【mysql的索引为什么使用B+树而不使用跳表?】
20 2
|
3天前
|
存储 算法 关系型数据库
MySQL索引详解
MySQL索引详解
15 0
|
3天前
|
存储 SQL 关系型数据库
完蛋!😱 我被MySQL索引失效包围了!
完蛋!😱 我被MySQL索引失效包围了!
|
3天前
|
SQL 存储 关系型数据库
MySQL的3种索引合并优化⭐️or到底能不能用索引?
MySQL的3种索引合并优化⭐️or到底能不能用索引?
|
3天前
|
存储 算法 关系型数据库
MySQL事务与锁,看这一篇就够了!
MySQL事务与锁,看这一篇就够了!
|
3天前
|
存储 SQL 关系型数据库
MySQL索引,看这一篇就够了!
MySQL索引,看这一篇就够了!

推荐镜像

更多