索引类似于书籍的目录,想找到书中某一个内容,我们需要先去找到对应的目录,定位对应的页码,MySQL存储引擎就是使用类似的方式进行查询,先去索引中查找对应的值,然后找根据匹配的索引值找到对应的行。
1、提高数据的检索效率,降低数据库IO成本:使用索引的目的就是可以缩小表中需要查询的记录从而加快数据检索速度。
2、降低数据的排序成本,降低CPU的消耗:索引之所以查的快,是因为它先对数据进行排序,若该字段正好需要排序,则降低了数据排序的成本。
1、占用额外的存储空间,它本质上就是一张表,它存着主键和索引字段,在磁盘上以索引文件的形式存在
2、数据更新效率变低,如果数据进行了更新的话,那么对应的索引也需要更新,从而降低了数据更新的速度。否则索引指向的物理数据可能不对,这也是索引失效的一个原因。
索引都是存储在存储引擎层的,主要有以下6种:
一句话:因为索引可以让我们避免全表扫描去查数据,提高了查询效率。
全表扫描
:全表扫描就是将整张表的数据全部或者分批次的加载到内存中,存储的最小单位是块或者页,它们是由多行数据来组成的,然后我们将这些块加载到内存里,然后通过轮询的方式去查找数据,找到我们需要的数据,然后返回。通常意义上,我们认为这样的查询方式是比较慢的,但也不是绝对意义的,当数据量很小的情况下,通过全盘扫描的效率更高,毕竟是基于内存的呀,肯定效率是比较快的。
简单回答一下就是:主键、唯一键或者普通键,只要具备区分一定数据的都可以作为索引
当前主流的就是B+树,还有Hash结构和BitMap等,其中MySQL不支持BitMap结构,同时基于InnoDB和MyISAM引擎的MySQL不显示的支持Hash结构。
在说B+树之前,先说一下二叉查找树、B树
hash结构呢,它就将关键字当做key,数据作为值来进行存储。它只适用于==或者in来进行检索,不支持范围查找,因为它是根据关键字来进行计算hash值的,所以只是某个关键字的一部分是不会找到这个数据的。而且它也不支持比较查找,因为,根据索引计算的hash值是不能确定原数据的大小的。它还有一个弊端如果在极端情况下,根据关键字的计算出的key然后定位到同一个桶中,那么它的结构也成了线性的了,查询效率倒不如B+树了。
它的锁粒度是非常大的,它在进行插入或者更新数据的时候,跟这个数据在同一个位图的数据操作都会被锁住,并不适合在高并发的情况下的联机处理系统。
它适合在并发较少,统计较多的场景中使用。
最后常用的就是B+树了,下面总结下为什么它是常用的:
这块的知识点,就由InnoDB和MyISAM两个存储引擎考虑开始。
聚簇索引的结构中:它的叶子结点包含的是对应的一条真正的数据。
非聚簇索引的结构中:它的叶子结点包括就只是索引值的信息和该行数据对应的物理地址。
MyISAM中不论是主键索引、唯一键索引和普通键索引,它都是非聚簇索引。
InnoDB中除了非聚簇索引,它还生成一个聚簇索引。InnoDB中的非聚簇索引的叶子结点包含的是主键索引信息。如果在设计表的时候指定了主键,那么这个主键生成的索引结构就是聚簇索引,如果没有指定,那就会指定该表的第一个唯一非空索引作为聚簇索引,再不满足的话,InnoDB内部会生成一个隐藏主键(密集索引),这个隐藏主键是一个6字节的列,该列的值会随着数据的插入而自增,也就是说我们的InnoDB必须有一个主键,而该主键就必须作为唯一的密集索引
因为InnoDB的主键索引和数据本身是存储在同一个文件当中的,因此在加载主键索引的文件的同时也将数据加载了进去。通过稀疏索引查找元素的话,会通过稀疏索引的B±Tree中检索该键,定位到主键信息,然后再进行一步操作,通过主键信息在主键索引中做检索操作,找到该行信息,这里就会出现一个覆盖索引的考点,如果select中查找的就是某个索引值的话,那么就不会进行回表查询了,这也就是常说的覆盖索引的情况
而MyISAM采用稀疏索引,主键索引放在一个文件,辅助键索引放在一个地方,而数据信息放在一个 独立的文件当中。两个索引的叶子结点都使用的是指向该文件的地址信息
表结构信息存储在 xxx.frm文件中,在InnoDB中,索引和数据都存储在 xxx.ibd文件中,而MyISAM的索引和数据是分开的,索引存放在xxx.MYI中,数据存放在xxx.MYD中的
首先会根据慢日志定位慢查询SQL,慢日志用来记录我们执行比较慢的SQL,如果一条SQL执行时间超过了10秒钟(默认),这条记录就会被放入到慢日志文件中。
可以使用explain等工具分析SQL
修改SQL,或者让SQL尽量走索引
假如我们现在使用联合索引,利用多个列创建一个索引(a,b),此时我们有一个查询语句:select * from table where a=xx and b=xx,他就可以使用到这个联合索引,而select * from table where b=xx就不能走这个联合索引了。
最左匹配:MySQL会根据where语句中的信息,从左往右一直找,直到遇到(<,>,between,like)就停止匹配,比如a=3 and b=4 and c>5 and d=6,这样一个信息,那么(a,b,c,d)这样一个联合索引就用不到了,而(a,b,d,c)这样一个索引就会被用到。a,b,c,d的顺序可以调整
== 和 in可以乱序,比如a=1 and b=2 and c=3 建立(a,b,c)索引可以任意顺序,mysql优化器可以优化成索引可以识别的形式。
为什么会有这样的成因呢:因为存储引擎会根据这个联合字段创建一个B+树,然后第一层就是a,也就是索引最左边的字段,它对应的元素是最左的,然后找到沿着符合a值的节点继续往下找。所以,如果一开始检索不是通过a字段来的,那么它就不会通过这个索引找到任何值。
答案肯定是否定的呀!假如我们的数据的量很少,但是索引建立的那么多,就相当于书的页数本来就少,我本可以通过从头找就很快找到,但是建立了很多的目录,先去找目录,然后根据目录再来找值,那不是费二遍事吗?哈哈。并且建立很多的索引,维护起来也很麻烦。所以综上来说,索引并不是建立的越多越好!