mysql事务索引


文章目录

  • mysql事务索引
  • 事务:
  • 并发事务出现的问题
  • 解决办法:事务四大隔离级别
  • 索引:
  • innoDB索引:
  • 联合索引和覆盖索引
  • 前缀索引
  • 索引相关问题:
  • 索引失效情况:
  • 索引设计原则:
  • mysql索引为什么选择使用B+树而不是其他的数据结构?


事务:

四大特性(ACID):

  1. 原子性
    概念:一个事务中的所有操作要么全部成功提交,要么全部失败回滚
    实现:通过uodo log回滚日志
    每条数据的增删改操作都伴随一条undo log的生成,并且回滚日志先于数据持久化到磁盘上
    怎么回滚?根据回滚日志做逆向操作
    比如在回滚日志里有新增记录,则生成相应的删除语句。有删除记录就生成相应的新增语句
  2. 一致性
    概念:事务把数据库从一个一致状态变换到另一个一致状态
    实现:通过其他三个特性来保证实现
  3. 隔离性
    概念:一个事务的执行不会被其他事务所影响
    实现:通过mysql四种隔离级别
  4. 持久性
    概念:事务提交成功后,对数据库数据的改变是永久的
    实现:通过redo log重做日志
    分为重做日志缓存和重做日志文件,因为mysql表数据是存储到磁盘上的,因此每次存取都要进行磁盘IO,而直接进行磁盘IO又是很耗性能的,所以为了提高性能会先将数据添加到缓冲池(Buffer Pool),再使用后台线程将数据保存到磁盘中。
并发事务出现的问题
  1. 脏读
    概念:事务A读取到事务B还未提交的数据
  2. 不可重复读
    概念:事务A前后两次读取到的数据不一样
    原理:事务A第一次读取之后,事务B进行了更新操作并提交,事务A再次读就发现数据变了
  3. 幻读
    概念:事务A查询数据发现没有,进行插入操作的时候又提示该数据已存在,就好像出现了幻觉
    原理:事务A查询之后,事务B进行插入操作并提交,由于幻读已经解决了不可重复读,所以事务 A再次读发现数据
解决办法:事务四大隔离级别
  1. 读未提交
    顾名思义,读取未提交的数据,不可解决任何问题
  2. 读已提交
    顾名思义,读取已提交的数据,可以解决脏读问题
  3. 可重复读
    顾名思义,可以重复读取,在这个事务持续期间禁止其他事务对这个字段的更新操作,可以解决脏读和不可重复读问题
  4. 可串行
    确保事务可以读取到相同行,在这个事务持续期间禁止其他事务的增删改操作,可以解决所有并发事务问题,但是性能很低

索引:

索引是什么?

帮助mysql高效获取数据的数据结构(B+树)。

相当于图书的目录,可以根据目录中的页码快速找到所需的内容。索引是用来提高检索效率的。

索引优劣

优:

  • 提高数据检索效率,降低数据库的IO成本
  • 可以通过索引进行排序

劣:

  • 索引要保存到磁盘,占用磁盘空间
  • 索引可以提高查询效率,但是会降低更新表的效率。进行增删改操作时,mysql不仅要保存数据,还要保存或者更新对应索引。

索引类型:

主键索引、普通索引、唯一索引、全文索引、前缀索引、联合索引

innoDB索引:

聚簇索引(主键索引、一级索引)和辅助索引(非聚簇索引、二级索引)

除了主键索引其他都是辅助索引.

聚簇索引:叶子节点保存每一行的行数据

辅助索引:叶子节点保存对应主键值(查询时可能需要进行回表查询)

联合索引和覆盖索引

联合索引:对两个或多个列建立的索引.

在建立索引时按最左边的列进行排序,左边列相同时再对下一列进行排序,依次类推

所以在组合索引中只有最左边的列是绝对有序的,而其他列无序。

最左前缀法则
联合索引索引了多列,要遵守最左前缀法则。
最左前缀法则指的是查询从索引的最左列开始,并且不跳过索引中的列,如果跳过某一列,该列后面的字段索引将失效。如果跳过了最左列,索引将失效变为全表扫描
ps:where条件后面索引中的字段顺序随便写,只要存在即可。但是order by后面的字段要按顺序写,否则会失效。

覆盖索引
使用辅助索引查找时,只查辅助索引字段值及对应主键值,不需要回表,直接返回数据,所以要避免使用select * 否则很容易出现回表查询,性能降低。

联合索引和单列索引:尽量使用联合索引,避免使用单列索引;联合索引使用得当,可以覆盖索引,避免回表。创建联合索引时考虑顺序,因为最左前缀法则。

前缀索引

字段类型为字符串(varchar,text等)时,有时候需要索引很长的字符串,这会让索引变得很大,查询时,浪费大量的磁盘IO,影响查询效率。
此时可以只将字符串的一部分前缀建立索引,大大节约索引空间,从而提高索引效率

索引相关问题:
索引失效情况:

1.不要在索引列上进行运算操作,索引将失效:where substring(phone,10,2)=‘15’

2.字符串不加引号,索引将失效:

3.模糊查询:头部模糊,索引失效,尾部模糊索引不失效

4.or前后只要存在非索引的列,索引将失效

5.联合索引中,出现范围查询(>,<),范围查询右侧的索引将失效(在不影响的情况下可以改为>=,<=)

6.数据分布影响:如果mysql评估使用索引比全表更慢,则不使用索引。走不走索引取决于表中数据的分布的,而不是一个固定的。如果返回的值是少部分则走索引,如果是大部分则直接全表扫描.

索引设计原则:

1.对数据量较大且查询频繁的表建立索引;
2.针对where查询条件以及orderby、groupby后面的字段建立索引
3.尽量选择区分度高的列作为索引,尽量建立唯一索引
4.建立前缀索引
5.建立联合索引
6.控制索引数量,索引越多,维护索引的代价越高,也会影响增删改的效率

mysql索引为什么选择使用B+树而不是其他的数据结构?

为什么不用二叉树(AVL,红黑树)?

平衡二叉树跟红黑树在大数据量等场景下,树仍然太高.

红黑树:通过舍弃严格的平衡和引入红黑节点,解决了AVL旋转效率过低的问题,但是在大数据量的场景下,树仍然太高,IO次数太多。

为什么用B+树而不用B树(B+树相对于B树有什么优点)
1.B+树的数据都在叶子节点上,查询效率更稳定
2.B树B+树的每一个节点的逻辑存储结构都是页,一页的大小都是固定的16k,而对于B树,无论是叶子节点还是非叶子节点,都会保存数据,这样就会导致一页中存储的键值减少,跟着指针也就减少,要保存同样大小的数据,就只能增加树的高度,导致性能下降。
3.B+树叶子节点采用双向链表,便于范围查询和排序,相比B-Tree来说,进行范围查找时只需要查找两个节点,进行遍历即可,而B-Tree需要获取所有节点,相比之下B+Tree效率更高。

为什么不用hash索引
hash索引只支持等值匹配(精准匹配),不支持范围匹配排序操作