0

MySQL索引,快速记忆法

 11 months ago
source link: https://www.51cto.com/article/755784.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

哈喽,大家好,我是了不起。面试的时候,面试官总喜欢问一些关于MySQL索引的问题,但是如果单纯的记忆,还是有难度的;今天了不起把MySQL索引的知识点进行汇总,方便大家快速记忆MySQL索引的相关知识点。赶快收藏此文章吧!

索引结构:B+树

索引其实是一种数据结构

注意B+树是MySQL,索引默认的结构;一张表至少有一个索引(主键索引),是可以有多个索引的

MySQL中的B+Tree

  1. 非叶子节点也叫内部节点,只存储 健值(主键的值) + 指针(存储子节点的地址信息)

主键索引:健值(主键的值) + 指针(存储子节点的地址信息)

非主键索引:非主键列的值 + 指向下一个节点的指针(存储子节点的地址信息)

  1. 所有的数据都存在叶子节点中;
  • 同时叶子节点上还存有一个指向相邻叶子节点的指针

  • 如果是聚簇索引(主键索引),叶子节点存储的是实际数据

  • 如果是非聚簇索引,则保存的是聚簇索引的索引key,也就是主键索引的值;查询非聚簇索引会有一个回表操作

  1. B+Tree的每个叶子节点增加了一个指向相邻叶子节点的指针,它的最后一个数据会指向下一个叶子节点的第一个数据,形成了一个有序链表的结构。

为什么B+ 树比B 树更适合作为索引?

  1. B+ 树的磁盘读写代价更低 B+ 树的数据都集中在叶子节点,分支节点 只负责指针(索引);B 树的分支节点既有指针也有数据 。这将导致B+ 树的层高会小于B 树的层高,也就是说B+ 树平均的Io次数会小于B 树。
  2. B+ 树的查询效率更加稳定 B+ 树的数据都存放在叶子节点,故任何关键字的查找必须走一条从根节点到叶子节点的路径。所有关键字的查询路径相同,每个数据查询效率相当。
  3. B+树更便于遍历 由于B+树的数据都存储在叶子结点中,分支结点均为索引,遍历只需要扫描一遍叶子节点即可;B树因为其分支结点同样存储着数据,要找到具体的数据,需要进行一次中序遍历按序来搜索。
  4. B+树更擅长范围查询 B+树叶子节点存放数据,数据是按顺序放置的双向链表。B树范围查询只能中序遍历。
  5. B+ 树占用内存空间小 B+ 树索引节点没有数据,比较小。在内存有限的情况下,相比于B树索引可以加载更多B+ 树索引。

MyISAM与InnoDB 的区别

  1. InnoDB支持事务,MyISAM不支持
  2. InnoDB支持外键,而MyISAM不支持
  3. InnoDB是聚集索引,数据和索引存到同一个文件里;MyISAM是非聚集索引,数据和索引不在同一个文件里;都是使用B+Tree作为索引结构
  4. InnoDB不保存表的具体行数,执行select count(*) from table时需要全表扫描。而MyISAM用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快(注意不能加有任何WHERE条件)

因为InnoDB的事务特性,在同一时刻表中的行数对于不同的事务而言是不一样的,因此count统计会计算对于当前事务而言可以统计到的行数,而不是将总行数储存起来方便快速查询。InnoDB会尝试遍历一个尽可能小的索引除非优化器提示使用别的索引。如果二级索引不存在,InnoDB还会尝试去遍历其他聚簇索引。

如果索引并没有完全处于InnoDB维护的缓冲区(Buffer Pool)中,count操作会比较费时。可以建立一个记录总行数的表并让你的程序在INSERT/DELETE时更新对应的数据。和上面提到的问题一样,如果此时存在多个事务的话这种方案也不太好用。如果得到大致的行数值已经足够满足需求可以尝试SHOW TABLE STATUS

那么为什么InnoDB没有了这个变量呢?

  1. InnoDB支持表、行(默认)级锁,而MyISAM仅支持表级锁
  2. InnoDB表必须有唯一索引(如主键)(用户没有指定的话会自己找/生产一个隐藏列Row_id来充当默认主键),而Myisam可以没有主键
  3. Innodb存储文件有frm、ibd,而Myisam是frm、MYD、MYI
  • Innodb:frm是表定义文件,ibd是数据文件

  • Myisam:frm是表定义文件,myd是数据文件,myi是索引文件

索引失效的场景

  1. 对索引列使用了函数、表达式或运算符:当查询条件中使用了函数、表达式或运算符时,MySQL就无法使用该列的索引,因为它需要对每行数据进行计算,而不是直接查找索引。
  2. 查询条件中使用了不等于操作符(<>、!=)、NOT NULL, NOT IN 等
  3. 模糊查询:当查询条件中使用了LIKE、%或_等模糊匹配符号时,MySQL无法使用索引进行快速定位。
  4. OR条件:当查询条件中包含多个OR条件时,MySQL无法使用索引进行快速定位。
  5. 范围查询:当查询条件中使用了BETWEEN、<、>、<=、>=等操作符时,MySQL只能使用索引中的一部分数据,需要读取更多的数据进行过滤,降低了查询效率。
  6. 数据类型不匹配,需要隐式转换类型
  7. 对索引列进行排序,因为它需要将数据按照指定的顺序进行排序
  8. 复合索引,如果不使用前列,后续列也将无法使用

正确的使用索引,能够显著提高数据库的查询效率。本文汇总了MySQL索引的常用知识点,帮助大家快速记忆,快快收藏吧。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK