美文网首页
7、mysql索引

7、mysql索引

作者: wuqingfeng | 来源:发表于2022-08-08 11:11 被阅读0次

    7.1 索引类型

    7.1.1 B-Tree索引

    我们谈论索引的时候,如果没有特殊说明,多半是指B-Tree索引。
    各种存储引擎以不同方式使用B-Tree索引,如MyISAM使用前缀压缩技术使索引变的更小,但InnoDB则直接使用原始数据。再如MyISAM通过索引数据的物理位置来引用被索引的行,而InnoDB则根据主键引用被索引的行。
    B-Tree索引抽象表示和举例图示如下:


    image.png image.png

    7.1.2 哈希索引

    哈希索引(hash index)基于哈希表实现。只有精确匹配所有的列,查询才有效。
    对于每一行数据,存储引擎会针对索引列计算出一个哈希码,哈希索引将哈希索引存在索引中,同时在哈希表中保存指向每个数据行的指针。
    在mysql数据库中,只有memory显式支持hash索引。
    InnoDB有一个功能,叫做自适应哈希索引(adaptive hash index),当InnoDB注意到某些索引值被使用的比较频繁时,它会基于B-Tree索引之上再创建一个哈希索引,不过这一过程是一个自动的,内部的行为,用户可以关闭该功能,但是不能对其进行配置。

    7.1.3 空间数据索引(R-Tree)

    MyISAM支持空间索引,可以用于地理数据存储。总体来讲,mysql对于GIS支持并不完善。

    7.1.4 全文索引

    全文索引是一种特殊的索引,它基于文本中的关键词进行查找,而不是比较索引中的值。

    7.2 使用索引优势

    使用索引可以为我们带来如下收益:

    • 减少服务器扫描数据量
    • 避免排序和临时表
    • 将随机IO转变为顺序IO

    7.3 高性能索引策略

    7.3.1 独立的列

    独立的列是指索引列不能是表达式的一部分,也不能是函数的参数。如对于下面的查询语句:

    SELECT actor_id FROM sakila.actor WHERE actor_id + 1 = 5;
    

    是无法使用索引的,我们在书写查询语句时,应当养成将索引行放在比较符号一侧的习惯。
    下面的查询语句:

    SELECT ... WHERE TO_DAVS(CURRENT_DATE) - TO_DAVS(date_col)<10;
    

    则将索引列当作函数参数放在了查询语句中,同样不能使用索引。

    7.3.2 前缀索引和索引选择性

    有时候需要索引很长的列,这会让索引体积变的很大。这时候可以索引开始的部分字符,从而达到节省索引空间,提升索引效率的目的。
    诀窍在于要选择足够长的前缀以保证较高的选择性,同时又不能太长以便节约空间。

    • 索引的选择性
      不重复的索引值(也称为基数,cardinality )和数据表的记录总数(#T)的比值,范围从1/#T 到1 之间。索引的选择性越高则查询效率越高,因为选择性高的索引可以让MySQL 在查找时过撞掉更多的行。唯一索引的选择性是1 ,这是最好的索引选择性,性能也是最好的。

    7.3.3 多列索引

    查询条件中包含and或者or时,where条件中的每一列创建单独的索引不是一个好的办法,需要使用顺序合适的多列索引才能获取更好的查询效果。
    如以下查询:

    --该查询数据源为mysql官方测试数据库数据
    mysql> explain select film_id,actor_id from sakila.film_actor where actor_id=1 or film_id=1\G
    *************************** 1. row ***************************
               id: 1
      select_type: SIMPLE
            table: film_actor
       partitions: NULL
             type: index_merge
    possible_keys: PRIMARY,idx_fk_film_id
              key: PRIMARY,idx_fk_film_id
          key_len: 2,2
              ref: NULL
             rows: 29
         filtered: 100.00
            Extra: Using union(PRIMARY,idx_fk_film_id); Using where
    1 row in set, 1 warning (0.01 sec)
    

    对该查询语句explain的结果中,type为index_merge,这通常表明服务器需要消耗较多的cpu和内存资源用于数据的缓存、合并、排序。

    7.3.4 索引顺序

    7.3.5 聚簇索引

    聚簇索引不是一种索引类型,是一种索引存储方式。
    当表使用聚簇索引时,它的数据行存储在了索引的叶子页(leaf page)上。具体如下图所示:


    image.png

    7.3.6 覆盖索引

    如果一个索引包含(覆盖)所需要查询的字段的值,我们称之为覆盖索引。

    7.3.7 使用索引扫描做排序

    mysql有两种方式可以生成有序结果:通过排序、按照索引顺序扫描。

    7.3.8 压缩索引

    7.3.9 冗余索引和重复索引

    7.3.10 未使用的索引

    未使用的索引完全时累赘, 建议删除。

    7.4 总结

    在mysql中,大多数情况下使用B-Tree索引,在选择索引和利用这些索引进行查询时,应当注意以下几点:

    1. 单行访问时很慢的。一次读取尽可能多的包含所需要的行。
    2. 按顺序访问范围数据时很快的。
    3. 覆盖索引是很快的。如果一个索引包含了查询所需要的所有的列,存储引擎就不需要再进行回表查询了,就避免了大量单行访问。

    相关文章

      网友评论

          本文标题:7、mysql索引

          本文链接:https://www.haomeiwen.com/subject/hrowwrtx.html