mysql

148 阅读3分钟

数据库索引

索引的原理

为什么用索引:

  1. 1.加快检索速度
  2. 2.唯一索引可以保证数据的唯一性

索引有缺陷吗?

  1. 1.索引也占空间

  2. 2.对数据进行增删改时,还要维护索引

  3. 3.创建索引和维护索引费时间

索引怎么提高查询速度?

将无序的数据变为有序的数据。就像给数据加了目录

使用索引的注意事项:

  1. 经常搜索的列上加索引
  2. 将长需要进行where判断的列上加索引
  3. 经常需要排序的列上加索引,
  4. 经常需要连接的列上加索引,加快连接速度

索引使用的主要数据结构

哈希索引

B+树索引

覆盖索引

如果一个索引,包含了所有需要查询的字段,就称为覆盖索引。

最左前缀原则

如果索引是联合索引,如User表的name和city加联合索引就是 (name,city), 如果查询的时候查询条件精确匹配索引的左边连续一列或几列,则此列就可以 被用到。

事务隔离级别: 隔离级别是通过加锁来实现的。

对数据库的访问通常是很多的,因此数据库一定做了很多支持并发的功能。

READ-UNCOMMITTED(读取未提交): 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻 读或不可重复读

READ-COMMITTED(读取已提交): 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读 仍有可能发生

REPEATABLE-READ(可重复读): 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修 改,可以阻止脏读和不可重复读,但幻读仍有可能发生。

SERIALIZABLE(可串行化): 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务 之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。

MySQL InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重读)

Mysql锁

数据库遵循两阶段锁协议,将事务分为两个阶段,加锁阶段和解锁阶段。

  • 加锁阶段:对数据进行读之前加共享锁,写之前加排他锁。加锁不成功则进入等待状态。知道枷锁成功才继续执行。
  • 解锁阶段:事务释放了一个锁以后,事务进入解锁阶段。该阶段只能进行解锁不能进行加锁操作。 事务 | 加锁/解锁处理 | | -------------------- | ---------------------------------- | | begin; | | | insert into test ….. | 加insert对应的锁 | | update test set… | 加update对应的锁 | | delete from test …. | 加delete对应的锁 | | commit; | 事务提交时,同时释放insert、update、delete对应的锁

如果不显示的用begin开启事务,执行语句时,会自动上锁。 用bigin显示开启事务,就会加锁,需要等commit后才会释放锁。不然就会不满足事务的隔离性,数据会在中途被其他事务修改。

意向锁:

假如有一个事务在执行,锁了某一行,这时候又执行了DDL语句,给表加一个字段,需要锁表,但是由于表里有一行记录被锁住了,锁表就会阻塞。 那么mysql在锁表时又是怎么知道有行锁呢? 如果是遍历每一行看是否有锁,性能就太差了。 mysql是怎么做的? 其实在获取行锁前,会先获取一个意向锁,表示将要加行锁。这样mysql判断行锁就不需要遍历了,只需要判读以下是否有意向锁就行了。