mysql索引有哪些,主流分为B+树索引、哈希索引、全文索引、空间索引四大类,B+树索引又细分主键索引、普通索引、唯一索引、联合索引、前缀索引,不同索引匹配不同查询模式,主键索引叶子节点存完整行数据,查询速度相对更快,联合索引遵循最左前缀原则,前缀索引只截取字符串前若干字符构建索引,适合长文本字段,哈希索引等值查询效率较高但不支持范围排序,全文索引用于关键词检索,空间索引处理地理坐标数据,你在innodb引擎下绝大多数业务场景优先选用B+树系列索引,myisam引擎也支持B+树索引但存储结构和innodb存在差异,该分类边界适用于mysql5.7、8.0稳定版本,memory引擎默认使用哈希索引,不适合需要排序、区间筛选的查询场景。

mysql索引之B+树索引细分类型

主键索引是特殊的唯一索引,一张innodb表只能有一个主键索引,不允许null值,innodb表的数据文件本身就是主键索引结构,也叫聚簇索引,你没有主动设置主键时,mysql会自动寻找非空唯一字段替代,找不到就内部生成隐藏主键。唯一索引限制索引列的值不能重复,允许单个null值,适合手机号、身份证这类需要去重校验的字段,查询时优化器有可能在匹配到一条数据后停止扫描。普通索引没有唯一性约束,只承担加速查询的作用,是业务里使用频次最高的索引类型,单列普通索引仅对单个字段建立。联合索引基于多个字段一起创建,字段顺序直接决定索引能不能生效,查询条件必须匹配左侧连续字段才能触发索引,调整字段顺序时要把区分度高、高频筛选的字段放在靠前位置。前缀索引针对char、varchar、text这类字符串类型,截取字段前面一部分字符建立索引,能够降低索引占用的存储空间,缺点是无法使用前缀索引做orderby和groupby,也不能用前缀覆盖索引。

选联合索引,优先区分度。

mysql索引之哈希、全文、空间索引

索引类型支持引擎擅长查询主要限制
哈希索引memory等值匹配不支持范围、排序、最左前缀
全文索引innodb、myisam文本关键词检索短停用词不会被索引,不适合精确过滤
空间索引innodb、myisam地理位置计算字段必须是geometry类型,语法门槛偏高

哈希索引底层是哈希表,输入查询值直接计算哈希码定位数据,等值查询响应很快,哈希冲突会带来额外扫描开销,它无法利用索引有序特性,大于、小于、between这类区间条件无法走哈希索引。全文索引可以替代like'%关键词%'这种低效写法,使用matchagainst语法检索文本,mysql内置停用词列表,短词汇、高频助词会被过滤,你想要检索这类词汇不能依靠全文索引。空间索引专门面向点位、多边形等地理数据,配合st_contains、st_distance这类空间函数使用,普通业务表单查询很少用到。

innodb引擎不原生支持用户手动创建哈希索引,它的自适应哈希索引是引擎内部自动维护的缓存结构,不受你直接控制,不能在建表语句里指定。自适应哈希索引会把访问频繁的B+树索引页缓存成哈希结构,用来加速热点等值查询,在高并发、查询波动大的场景下,开启自适应哈希索引有可能增加锁竞争,部分业务会选择关闭这个特性。

覆盖索引不属于独立索引结构,它是一种索引使用形态,当查询需要的全部字段都存在于索引中,不需要回表读取主键索引的数据,就构成覆盖索引,执行计划里extra列会显示usingindex,能够明显减少IO开销,设计联合索引时可以把查询要返回的字段追加到索引末尾来构造覆盖索引。

索引下推是innodb的查询优化机制,和索引类型无关,在联合索引匹配最左前缀之后,mysql会在索引层直接判断后续索引字段的过滤条件,不用先回表再过滤数据,mysql5.6及以上版本默认开启这个功能,能减少回表次数。

索引不是越多越好,每一条写入、更新、删除语句都要同步修改对应索引,索引数量较多时,写入性能会逐步下降,单表索引数量建议控制在合理范围,不要为了少量低频查询随意新建索引,废弃索引要及时清理。

执行explain查看type列,ref、range、eq_ref代表索引正常生效,all代表全表扫描,你可以依靠这个手段验证索引是否被优化器选中,部分情况下优化器判断全表扫描代价更低,即使索引存在也会放弃使用索引。