您的位置:首页 > 数据库 > MySQL

做一个合格的程序猿之MYSQL存储引擎INNODB简介--初识索引(三)

2016-03-05 10:41 906 查看
  mysql的Innodb存储引擎中的索引大概分三种,哈希索引,全文索引,和常用的B+树索引

  1)全文索引,以前Innodb是不支持全文索引的,最近的版本才开始支持,即使目前支持了,用的人也是相对较少的,全文索引在企业中的需求是对用户所输入的信息进行全文匹配,可能匹配某个产品的信息中的介绍文本,价格,简介,说明,等海量的信息,如果把这些信息全部放在mysql中,相对不太现实,第一是数据量太大的问题,第二是搜索效率的问题,第三就是索引实时更新的问题,目前mysql都不能完美的解决这些问题

     而且,目前企业级应用的全文搜索引擎大部分都是基于Lucene的Solr和elasticsearch,Solr相对较新的版本至少5.0版本之后已经全面支持分布式搜索,elasticSearch最近更是如火如荼,最新版本已经到了2.x,相对于1.x和0.x版本有了新的质变,elasticSearch是自动支持分布式架构,索引文件分布在多台节点之上,性能也不错,Solr支持与zookeeper整合,提供高效的分布式搜索服务,并且支持实时搜索,所以相对而言,mysql在全文搜索这一块并不是很擅长,只是支持而已

 2)哈希索引,哈希索引是系统自己管理维护的,且对范围查询无效,生成的条件相对比较苛刻,当用户多次调用相同的查询sql,例如select * from user where user_name = xxx

这样的sql连续调用多次(貌似要超过100次),此时mysql实例会自生成哈希索引,且建立索引的速度很快,大大的加快的查询的效率,mysql默认是打开自适应的哈希索引的,如下图:

show variables like 'innodb_adaptive_hash_index'




3)B+数索引

     上述2个索引我们开发人员能使用或者能控制的并不多,也不是相对灵活,但B+树索引,是我们日常开发中最常用的索引,当你使用如下SQL时,默认生成的索引类型就是B+树索引

ALTER TABLE xxxx ADD INDEX xxx_index (xxx列);

   

  3.1 聚簇索引

        可以这样说,innodb的表即是索引,因为所有的表数据是按照主键来构造一个B+树,叶子节点存放表的每行数据,如果某表没有主键,mysql会自动生成一个row_id来做该表的主键,同样会生成一颗树,类似这样



                                                                                            (图片来自于Mysql技术内幕 Innodb存储引擎)

聚簇索引的好处就是如果某sql是根据主键查询会非常快,因为mysql内部只需要一次查询(叶子节点即数据),且是顺序查找,所以查询速度会非常快

 3.2 非聚簇索引

    非聚簇索引是相对于聚簇索引来说的,也可以称为二级索引,辅助索引,建立方法如下:

ALTER TABLE xxxx ADD INDEX xxx_index (xxx列1,xxx列2,xxx列3);

形成的索引结构如下:



                                       (图片来自于Mysql技术内幕 Innodb存储引擎)

非叶子节点中保存着索引值,叶子节点中保存着一些基本信息,主要包括的信息有(xxx列1值,xxx列2值,xxx列3的值,该行数据主键id),也就是说非聚簇索引叶子节点中包含的信息并不是该行的所有信息,如果你的sql语句是select xxx4列 from xxx_table where xxx列1 = 1 and xxx列2 = 2 and xxx列3 = 3 这种sql的话,你需要的返回值并不在非聚簇索引的叶子节点中,此时还需继续查询,根据非聚簇索引叶子节点中返回的主键id,再根据主键id去聚簇索引中,查询xxx列4的信息,如下图所示:



                                                                                     (图片来自于Mysql技术内幕 Innodb存储引擎)

也就是说你的查询sql并没有覆盖索引叶子中的信息,这就是下一个概念,覆盖索引

  覆盖索引,顾名思义,你的sql查询结果所需要的信息,正好可以在非聚簇索引中的叶子节点中,例如如下sql:

select xxx3列 from xxx_table where xxx列1 = 1 and xxx列2 = 2 这样的sql可以大大的减少IO的次数,提高查询效率,因为此时你无需再根据非聚簇索引中的id再去主键索引中再次查询其他的信息,这就是为什么我们开发过程中写select * from xxx_table where xxx1列 = 1 and xxx2列 = 2的弊端之一了,返回所有字段,其实有些字段我们根本没有在应用程序中用到,我们也全量返回,这样会影响查询效率的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息