索引是一种数据结构,用来提高查询效率。

    (那么多的数据,当然要想办法提高查询效率啦啊)

  常见的索引有Hash 索引  和  B+树索引。

  Hash索引和B+树索引的区别?

    Hash索引适合做等值查询;hash会出现hash碰撞,如果hash碰撞严重,查询效率就会降低。 (Nosql中就是用的 k-v,也就是用的hash了)

    B+树可以进行范围查询,联合查询的最左匹配原则,

  B+树和B树的区别?

    B树是一种多路平衡树。

      子树的个数等于结点中的元素的个数+1;

      查询可以在非叶子结点命中;

      一个M阶的B树,根节点至少有两个元素,非根节点的元素个数为 [ M/2, M ] 

    B+树在B的基础上进行了改进:

      子树的个数等于结点的元素的个数;

      查询都是在叶子结点命中;

      叶子结点有指向两边的指针,用于范围查询。

    B*树在B+树的基础上进行了改进:

      非根结点的元素的个数至少为2/3M,

      非叶子结点也加入了指向两边的指针

    为什么不用二叉搜索树?

      二叉搜索树的效率近似于二分查找,效率高于B+树,但是考虑到IO操作的时间,果断选取B+树。(树越扁平越好)

  为什么建立了索引却没有走索引?

 

  索引失效?

  

  聚簇索引 非聚簇索引

    聚簇索引:    指的是叶子结点中存储的数据   ( innodb采用的就是聚簇索引,因此它的存储文件就只有两个)

    非聚簇索引: 指的是叶子结点中存储的数据的地址 (MyIsam采用的是非聚簇索引,因此它的存储文件有三个)

    聚簇索引也叫 主键索引、一级索引,那么相对应的就有非主键索引、二级索引、普通索引,它的叶子结点存储的就是主键索引的值,还要进行一次回表查询,可以通过建立覆盖来不进行回表

  主键索引和普通索引的区别?

     普通索引还需要进行回表。

  那怎么可以不进行回表?

    通过覆盖索引!!覆盖索引,是通过联合索引来实现的!

  联合索引

    联合索引就是多个字段建立索引,联合索引要符合最左前缀匹配原则,注意!!这地方有的时候查询可能不走索引,就是因为不符合最左前缀匹配原则。

      比如:我们通过 (name,age,adress)建立了联合索引。

      比如 select * from T where age=19 and address='sd'  联合索引失效,不符合最左前缀匹配原则

        select * from T where name like '%fa'   联合索引失效,不符合最左前缀匹配原则

  索引下推:

    在联合索引中就进行判断是都满足条件,不满足添加的不进行回表,如果不进行索引下推,

      比如 selct * from T where name like '张%' and age=9;     符合最左前缀原则,但是如果不支持索引下推,就会忽视掉age这个字段,找到所有符合添加的name, 然后回表,查出完整记录后,再进行age的比较。如果支持索引下推,就会先比较age的值,不满足的就直接不进行回表了!

  为什么要有自增主键?

    这就涉及到了索引的维护,数据的添加和删除,会破坏索引的结构,调整索引需要消耗时间,采用自增主键,就可以之间往后添加元素就可以了,不需要做大的索引结构的变动。

  普通索引和唯一索引:

    唯一索引就是索引的字段值不会重复。那么在查询的时候,通过唯一查询可以查询到一条记录,通过普通查询,还需要继续向后查询,找到第一个不满足查找的索引结束。 这个差别并不大。

    两者真正的差别在插入数据上面。这里用到了 Change Buffer

    如果要操作的页在内存中,那直接操作内存即可。如果不在内存中,那就可以使用Change Buffer, 只有普通索引才可以用change buffer,因为唯一索引还要判断索引是否冲突!!而且如果,插入后,马上进行查询,还是会要进行磁盘IO,然后将Chage buffer的内容写到页中,然后再进行查询(显然,这不但没提高效率,还降低了效率)。如果没有进行查询,则再适合的时间进行change buffer写到磁盘中。所以 change buffer适合用在写多读少的地方。注意:这个根redolog并不冲突,在change buffer中的修改,也会写到 redolog中,进行持久化。

    change buffre 减少了随机读磁盘的io消耗(本应该将数据从磁盘中读进内存进行更新,但是为了提高速度,先不读取到内存中了,直接在内存中的change buffer区域进行更新操作),redo log节省了随机写磁盘的io消耗(改为按顺序写)(redolog是在更新数据库的时候用到的,这时候在内存中已经修改了数据了,但是还没有写回磁盘)

  (所以,意思就是尽量使用普通索引) 

  Mysql在执行时索引是怎么选取的?

    Mysql在执行sql语句时,用哪个索引是由mysql的优化器决定的!!通过 explain可以看到它实际走的索引

      (优化器 通过判断 扫描行数、是否使用临时表、是否排序等进行综合判断,来选取使用哪个索引)

  怎么给字符串字段加索引?

    比如给邮箱地址加上索引。可以采用取字符串给的前面几位作为索引!!

      (心中要记住一点,建立索引关注的是区分度!! 要看一下前几位的区分度就比较好了,将让前面这些位做索引!)

      但是使用了前缀索引,就没法用覆盖索引了!!因此这时,必须要回表进行比较字符串的完整值是否匹配.

    对于身份证这样的建立索引,可以采用反转,然后取前几位的方式;或者加一个字段,存储它的hash值,用hash来作为索引。

  

 

也许会有遗憾,但是不应该在失败之前