MYSQL系列——索引知识点归纳

MYSQL系列——索引知识点归纳

内容整理范围来源较广,若涉及原作者引用,立即更新。

文章目录

  • MYSQL系列——索引知识点归纳
  • 一、索引使用及分类
    • MYSQL索引分类
      • 索引创建:
        • 普通(二级)索引:
        • 唯一索引:
        • 主键索引:
        • 前缀索引:
        • 后缀索引(suffix index)(一般不用)
        • 全文索引:
        • 组合索引:
        • 降序索引的应用
        • 自适应哈希索引
          • 开启自适应hash索引
          • 触发器维护hash值:
          • 哈希索引使用情况查看
            • 插入缓冲和自适应哈希索引
          • 哈希索引弊端
    • 索引原理
      • B+树
        • B+树的特征:
        • B+树的优势:
        • B+树分裂原理(基于mysql8版本)
        • 启发式优化规则(MYSQL8版本)
      • 聚族索引
        • 聚族索引的目的
        • 聚族索引的弊端:
        • 聚族索引原理
        • 辅助索引
      • LSM-TREE概述
    • 索引设计
      • 建立的索引是否适合
        • 三星索引构建:
      • 相关知识点
        • 数据扫描方式:
        • IO逻辑
  • 二、MYSQL索引问题排查
    • 相关参数
      • 检查是否禁用索引扩展提高性能
      • Handler类参数调用
    • 索引失效场景汇总
    • 注意事项:
    • 索引统计
    • 二级索引快速建立
      • Innodb快速在线索引创建功能
      • 索引并行相关参数
    • 索引-----锁关系
    • 索引使用情况查询工具推荐-----pt-index-usage
    • 冗余索引查询工具-----pt-duplicate-key-checker

一、索引使用及分类

MYSQL索引分类

索引创建:

普通(二级)索引:

create index index_name on table_name(column_list);
alter table table_name add index(column_list);

唯一索引:

#允许为空,防止数据重复
create unique index index_name on table_name(column_list);
alter table table_name add constraint constraint_name unique key(name1,name2);

主键索引:

alter table table_name add PRIMARY key(‘column’)

前缀索引:

alter table city_demo add key (city(7));
#前缀索引不支持order by 、group by ;也无法做到覆盖扫描;
#区分度检测(前缀长度经过测试为7为最佳;如果再增加前缀长度,选择性提升幅度就很小了)
select count(distinct right(shi_Guid,6))/count(*) from ZhuanJia_Info;

后缀索引(suffix index)(一般不用)

例如查找某个域名的所有电子邮件地址;MYSQL原生不支持反向索引,但可以把字符串反转后存储,基于此建立前缀索引通过触发器来维护这种索引

全文索引:

create table test(
id int auto_increment not null primary key,
title varchar(200),
body TEXT,
fulltext(title,body)
)type=myisam;

CREATE TABLE article (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR (200),
body TEXT,
FULLTEXT (title, body) WITH PARSER ngram ## 全文索引
) ENGINE = INNODB DEFAULT CHARSET=utf8mb4 COMMENT=‘文章表’;
#创建
alter table test add FULLTEXT index idx_name (name)
ALTER TABLE article ADD FULLTEXT INDEX title_body_index (title,body) WITH PARSER ngram;
#自然语言搜索模式 (默认)
SELECT * FROM article WHERE MATCH (title,body) AGAINST (‘精神’ IN NATURAL LANGUAGE MODE);
SELECT * FROM article WHERE MATCH (title,body) AGAINST (‘精神’);

#索引不支持查询字符串:
SELECT * FROM information_schema.INNODB_FT_DEFAULT_STOPWORD;

组合索引:

alter table a add index idx_sellname_gmt_sellid(gmt_create,seller_name,seller_id);
#最左前缀原则:
1、where 条件调用组合索引最左边的字段才会触发组合索引,当遇到范围查询(>、<、between、like)停止匹配,后面字段不会使用索引;
2、字段顺序无影响,MYSQL内部会自动优化;
3、基于B+树特点,所有叶节点存储在同一层,组合索引可以最大发挥B+树顺序查找优势;
4、ORDER BY列跟在匹配列(它们都使用等值条件)的后面,从而规避了排序;则该查询只需访问索引而无须回表;
例如:
对(a,b,c,d)建立索引,查询条件为a = 1 and b = 2 and c > 3 and d = 4,那么a、b和c三个字段能用到索引,而d无法使用索引。因为遇到了范围查询。
#分页优化(深度分页问题)

update tb_user_info set user_img=replace(user_img,'http://','https://') limit 1,1000;

mysql的limit游标进行的范围查找原理,是下沉到B+数的叶子节点进行的向后遍历查找,在limit数据比较小的情况下还好,limit数据量比较大的情况下,效率很低接近于全表扫描。
如果对于有where 条件,又想走索引用limit的,必须设计一个索引,将where 放第一位,limit用到的主键放第2位,而且只能select 主键!

SELECT * FROM table WHERE ID>=( SELECT ID FROM table ORDER BY ID LIMIT 90000,1) limit 100;

降序索引的应用

对单列进行排序,5.7和8版本没区别;MySQL8.0开始真正支持降序索引,只有InnoDB引擎支持降序索引,且必须是BTREE降序索引,MySQL8.0不再对group by操作进行隐式排序。

当查询需要对多列排序,顺序要求不一致时,就可以使用降序索引来避免filesort了;

索引定义中的DESC不再被忽略,而是按降序存储键值。以前,可以以相反的顺序扫描索引,但是会导致性能损失。下行索引可以按前向顺序扫描,效率更高。当最有效的扫描顺序混合了某些列的升序和其他列的降序时,降序索引也使优化器能够使用多列索引。

降序索引利用的是MYSQL的反向扫描;
在8版本的explain中,extr新增了 Backward index scan 专门描述反向扫描;

自适应哈希索引

MySQL并没有显式支持Hash索引,而是作为内部的一种优化。具体在Innodb存储引擎里,会监控对表上二级索引的查找,如果发现某二级索引被频繁访问,二级索引成为热数据,就为之建立hash索引。因此,在MySQL的Innodb里,对于热点的数据会自动生成Hash索引。
一般情况下查找时间复杂度为O(1),仅需一次查找就能定位数据;
#自适应哈希索引是通过缓冲池的B+树页构造的;建的很快,而且不需要对整张表构建哈希索引;innodb会自动根据访问的频率和模式来自动为某些热点页建立哈希索引
据官方解释:启动AHI后,读取和写入速度可提高2倍,辅助索引连接操作性能提高5倍;无需人工对数据库调整;
#仅使用=或<=>非常快;
#不能适用于order by;
#只能使用整个键来搜索行;

#MEMORY引擎默认使用哈希索引,将键的哈希值和指向数据行的指针保存在哈希索引中。
优点:访问速度较快。
缺点:
哈希索引数据不是按照索引值顺序存储,无法用于排序。
不支持部分索引匹配查找,因为哈希索引是使用索引列的全部内容来计算哈希值的。
只支持等值比较,不支持范围查询。
当出现哈希冲突时,存储引擎需要遍历链表中所有的行指针,逐行进行比较,直到找到符合条件的行。

开启自适应hash索引

在等值查询确实会提升效率50%以上;
#前提条件
AHI的要求是对这个页的连续访问模式必须一样;
例如:对于(a,b)这样的联合索引页,其访问模式可以是:
where a=xxx
where a=xxx and b=xxx
1)访问模式一样是查询条件一样,如果交替进行,则Innodb不会对该页构造AHI;
2)按该模式访问了100次
3)页通过该模式访问了N次,其中N=页中记录*1/16;

内部判断索引值使用非常频繁,会基于BTree上创建一个哈希索引,这种哈希查找是内部行为,如果有必要可以关闭该功能
set global innodb_adaptive_hash_index=0;

哈希索引可以提高查询性能,但是,在高并发情况下,会造成 RW-latch争用,进而堵塞进程。可以使用命令“show engine innodb status\G;”来监控SEMAPHORES
由于自适应哈希索引造成大量的锁争用, 进而堵塞很多进程,最终导致MySQL崩溃重启。
InnoDB: Warning: a long semaphore wait --Thread 140570431108864 has waited at btr0cur.c line 528 for 241.00 secondsthe semaph


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部