索引是一种用于快速查询和检索数据的数据结构,其本质可以看成是一种排序好的数据结构。索引的作用就相当于书的目录。打个比方: 我们在查字典的时候,如果没有目录,那我们就只能一页一页的去找我们需要查的那个字,速度很慢。如果有目录了,我们只需要先去目录里查找字的位置,然后直接翻到那一页就行了。索引底层数据结构存在很多种类型,常见的索引结构有: B 树, B+树 和 Hash、红黑树。在 MySQL 中,无论是 Innodb 还是 MyIsam,都使用了 B+树作为索引结构。
索引的存储原理大致可以概括为一句话:以空间换时间。
一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往是存储在磁盘上的文件中的(可能存储在单独的索引文件中,也可能和数据一起存储在数据文件中)。
数据库在未添加索引进行查询的时候默认是进行全文搜索,也就是说有多少数据就进行多少次查询,然后找到相应的数据就把它们放到结果集中,直到全文扫描完毕。
索引的优点包括:大大提高数据查询速度,提高数据检索的效率,降低数据库的IO成本,通过索引列对数据进行排序,降低数据的排序成本,被索引的列会自动进行排序,包括【单例索引】和【组合索引】,如果按照索引列的顺序进行排序,对order by语句来说,效率就会提高很多。
然而,索引也有一些缺点,比如会占据磁盘空间,降低更新表的效率,维护索引需要消耗数据库资源。此外,使用索引并不一定能够带来很大提升,特别是在数据库的数据量不大的情况下。
索引的分类包括按「数据结构」分类、按「物理存储」分类、按「字段特性」分类和按「字段个数」分类。常见索引类型有主键索引、唯一索引、复合索引、全文索引、空间索引和前缀索引。
要判断SQL是否走索引,可以通过explain关键字查看这条语句的执行计划。key字段显示实际使用的索引,type字段显示查询使用了何种类型,rows字段大致估算出找到所需的记录所需要读取的行数。
索引失效的原因包括左或者左右模糊匹配、在查询条件中对索引列使用函数、对索引列进行表达式计算、隐式类型转换、联合索引未遵循最左匹配原则以及在WHERE子句中使用OR导致索引失效。
索引能提高查询性能的原因在于,索引通过多阶使树的结构更矮胖,减少I/O次数;通过B+树,把业务数据与索引数据分离,提高单次I/O有效数据量;通过树数据的有序和「二分查找」,大大缩小查询范围;针对的是单个字段或部分字段,数据量本身比一条记录的数据量要少的多,这样即使通过扫描的方式查询索引也比扫描数据库表本身快的多。
MySQL 默认的存储引擎 InnoDB 采用的是 B+ 作为索引的数据结构,原因在于B+ 树的非叶子节点不存放实际的记录数据,仅存放索引,因此数据量相同的情况下,相比存储即存索引又存记录的 B 树,B+树的非叶子节点可以存放更多的索引,因此 B+ 树可以比 B 树更「矮胖」,查询底层节点的磁盘 I/O次数会更少。
如何判断sql是否走索引?