Mysql索引知识的自我总结

首先解释一下什么叫索引,举个例子简单说明就是当你读书的时候,假设就读的《活着》,你想迅速找到富贵他爸是什么时候死的,你不可能整本书一页一页翻吧,肯定是通过目录找到和福贵同时期的章节,在章节里面寻找把。此时的目录就相当于索引对于数据库的作用,可以更快的找到内容,那么索引是由什么来实现的呢,目前为止mysql最常用的索引是由b+树来实现的,为什么要用b+树呢?这就有一套优化提升的过程了,首先对于大数据的查找我们肯定首先想到的数据结构就是二叉树虽然基本情况二叉树查询的速率就是logn但是当用户按照顺序插入的时候,它就成了一条直线退化成链表,此时再查找速率又成了n,对于这种情况好理解啊我们设置成二叉平衡树,让它不退化就行了呗,但是转念一想如果一直二叉树,我一直一层一层的传下去,当我数据特别特别多的时候速度也还是很慢啊,此时我们就想到多叉树,也就是所说的b树,那都到这里的,为啥不直接用b树呢?那就要说b+树和b树的区别,首先最大区别就是b+树的叶子节点要放实际的记录数据,而不仅仅只是索引,而且b+树的叶子节点是用链表连接的,查找起来更加的方便,所以目前为止,mysql的索引都是用b+树,而且还有一个原因就是mysql的三大存储引擎都支持b+树,既然介绍完索引的基本组成,那么再说一下索引的基本分类,索引按照物理存储来分主要分成两个大类,分别是聚簇索引也就是所谓主键索引,剩下的就叫二级索引。还有一种比较常见的就是按字段个数来分类,分成单列索引和联合索引,首先先来说一下二级索引和聚簇索引,首先关于这两类要是在第一次查找索引就获得了此时需要的的值,此时就叫做覆盖索引,要是此时我先查找的二级索引,二级索引获取到了此时的主键,再去根据主键通过聚簇索引找到了所需要的值那么此时就叫做回表,再然后就是对于单列索引和联合索引的区分其实这里面我觉得最重要的就是最左匹配原则,举个例子此时有个学生对象,我把姓名和性别这两列创建了一个联合索引,如果我此时select 查找的条件是姓名为面包性别为男,此时就符合最左匹配原则先通过姓名索引找到面包的所有内容,再根据性别索引查找,但如果此时查询的条件只是性别为男,没有姓名那么此时就不符合最左匹配原则此时就只能全表扫描或者是性别匹配的有其他索引。既然说了这么久的索引哪么此时讲解一下什么时候需要索引什么时候不需要索引能,不可能我每时每刻的查找都要索引吧,首先就是字段有唯一性的例如图书编号这种,还有就是经常使用where的场景可以使用索引,还有就是经常使用order by group by的这些的时候,因为使用了索引就不用他们再排序一次节省了很多时间,既然有好处那么也得说说不好的地方,首先索引的创建会造成空间,建立的多了自然空间消耗就越多,而且维护索引也需要时间。谈到了索引的坏处那我们再想想有没有什么办法来优化一下我们已经创建了的索引呢?当然有,首先就是前缀索引优化,这主要针对一些字符串,我们只截取前面的几个字符来作为索引,这样子的话空间是优化了但是还是会造成一点不好的就是截取后的索引不能做为覆盖索引了也不能适用于orderby中了,还有就是对于覆盖索引优化,就是我们的聚簇索引叶子节点不是存储了此时的记录吗?那就把我此时聚簇索引的列和其他有可能查询的列,弄成联合索引,这样子的话避免了回表,减少了io操作。还有个最重要的就是主键索引最好是自增的,为什么呢?如果我们使用自增主键,那么每次插入的新数据就会按顺序添加到当前索引节点的位置,不需要移动已有的数据,当页面写满,就会自动开辟一个新页面。因为每次插入一条新记录,都是追加操作,不需要重新移动数据,因此这种插入数据的方法效率非常高。另外,主键字段的长度不要太大,因为主键字段长度越小,意味着二级索引的叶子节点越小(二级索引的叶子节点存放的数据是主键值),这样二级索引占用的空间也就越小。ok到这里索引的相关操作也差不多了,那在我们运用索引的过程中索引会不会突然抽了一下失效呢?这是肯定会出现,首先就是当我们在模糊查询的时候也就是 like %xx 或者 like %xx%这两种方式都会造成索引失效,因为此时数据库不能根据值来准确的查找索引;当我们在查询条件中对索引列做了计算、函数、类型转换操作,这些情况下都会造成索引失效道理也和上面的一样;还有就是当我们使用联合索引的时候,没有满足最左匹配原则的时候索引也会失效;在 WHERE 子句中,如果在 OR 前的条件列是索引列,而在 OR 后的条件列不是索引列,那么索引会失效。这是因为数据库优化器评估认为,单独使用一个索引并不能显著提高整体查询效率,它需要评估两种情况(通过索引查找和全表扫描)的成本,最终很可能决定直接进行全表扫描,尤其是在数据量不是非常大,且OR条件中涉及未索引列的情况下。

你可能感兴趣的:(mysql,数据库)