MySQL索引

MySQL索引

  • 索引介绍
  • 索引原理与分析
  • 组合索引
  • 索引失效分析

索引介绍

  • 什么是索引
    索引:包括聚集索引、覆盖索引、组合索引、前缀索引、唯一索引等,没有特别说
    明,默认都是使用B+树结构组织(多路搜索树,并不一定是二叉的)的索引。
    存储:存储在磁盘文件中
    索引是帮助MySQL高效获取数据的数据结构。更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度。
  • 索引的优势和劣势
    优势:提高数据的检索效率,降低数据库的IO成本;对数据进行排序
    劣势: 占据磁盘空间,降低更新表的效率
  • 索引的分类
    单列索引、组合索引、全文索引、空间索引
  • 索引的使用
创建索引
CREATE INDEX index_name ON table(column(length)) ;
ALTER TABLE table_name ADD INDEX index_name (column(length));
//唯一索引:
CREATE UNIQUE INDEX index_name ON table(column(length)) ;
alter table table_name add unique index index_name(column);
//全文索引:
CREATE FULLTEXT INDEX index_name ON table(column(length)) ;
alter table table_name add fulltext index_name(column)
//组合索引:
ALTER TABLE article ADD INDEX index_titme_time (title(50),time(10)) ;
删除索引:
DROP INDEX index_name ON table
查看索引:
SHOW INDEX FROM table_name \G

索引原理与分析

  • 索引的存储结构
    索引的存储结构:

不同的存储引擎,会使用不同的索引
MyISAM和InnoDB存储引擎:只支持B+ TREE索引, 也就是说默认使用BTREE,不能够更换
MEMORY/HEAP存储引擎:支持HASH和BTREE索引

  • B树和B+树:
    B树
    B树和B+树的最大区别在于非叶子节点是否存储数据的问题。
  • B树是为了磁盘或其它存储设备而设计的一种多叉(下面你会看到,相对于二叉,B树每个内结点有多个分支,即多叉)平衡查找树。
    B树的高度一般都是在2-4这个高度,树的高度直接影响IO读写的次数。
    如果是三层树结构---支撑的数据可以达到20G,如果是四层树结构---支撑的数据可以达到几十T
    B树是非叶子节点和叶子节点都会存储数据。
    B+树只有叶子节点才会存储数据,而且存储的数据都是在一行上,而且这些数据都是有指针指向的,也
    就是有顺序的。 索引列 order by
  • 非聚集索引(MyISAM)
    B+树的索引不在一起就是非聚集索引
    非聚集索引一般包含主键索引 和辅助索引都会存储指针的值。
  • 聚焦索引(InnoDB)
    数据和索引在一起就是聚焦索引。
    主键索引的叶子节点会存储数据行。辅助索引只会存储主键值。
    主键索引:1.InnoDB 要求表必须有主键(MyISAM 可以没有),如果没有显式指定,则 MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL 自动为 InnoDB 表生成一个隐含字段作为
    主键,类型为长整形。
    辅助索引:2.第二个与 MyISAM 索引的不同是 InnoDB 的辅助索引 data 域存储相应记录主键的值而不是地址。换句话说,InnoDB 的所有辅助索引都引用主键作为 data 域。
select * from user where name='Alice' 回表查询 检索两次 非主键索引 --- pk---索引--->数据
select id,name from user where name='Alice' 不需要回表 在辅助索引树上就可以查询到了 覆盖索
引(多用组合索引)

引申:为什么不建议使用过长的字段作为主键?
因为所有辅助索引都引用主索引,过长的主索引会令辅助索引变得过大。
同时,请尽量在 InnoDB 上采用自增字段做表的主键。

  • MyISAM 和 InnoDB的存储结构


    InnoDB 主键索引

    辅助索引

组合索引

  • 哪些情况需要创建索引

    1. 主键自动建立唯一索引
    2. 频繁作为查询条件的字段应该创建索引
    3. 多表关联查询中,关联字段应该创建索引 on 两边都要创建索引
    4. 查询中排序的字段,应该创建索引
    5. 频繁查找字段 覆盖索引
    6. 查询中统计或者分组字段,应该创建索引 group by
  • 哪些情况不需要创建索引

    1. 表记录太少
    2. 经常进行增删改操作的表
    3. 频繁更新的字段
    4. where条件里使用频率不高的字段
  • 为什么儿使用组合索引
    为了节省mysql索引存储空间以及提升搜索性能
    ALTER TABLE 'table_name' ADD INDEX index_name('col1','col2','col3')

  • 索引原则

    1. 一颗索引树上创建3个索引 : 省空间
    2. 三颗索引树上分别创建1个索引, 更容易实现覆盖索引
    3. 遵循最左前缀原则
      - 前缀 索引 like a%
      - 从左到右匹配直到遇到范围查询 > < between like
      - 创建组合索引(a,b,c,d) where a=1 and b=1 and c>3 and d=1 到 a>3 停下来了
      - (a,b,d,c) create index idx_com on t1(a,b,d,c);

索引失效分析

  • 查看执行计划 explain
    id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra
  • 案例数据
--用户表
create table tuser(
id int primary key,
loginname varchar(100),
name varchar(100),
age int,
sex char(1),
dep int,
address varchar(100)
);
--部门表
create table tdep(
id int primary key,
name varchar(100)
);
--地址表
create table taddr(
id int primary key,
addr varchar(100)
);
--创建普通索引
mysql> alter table tuser add index idx_dep(dep);
--创建唯一索引
mysql> alter table tuser add unique index idx_loginname(loginname);
--创建组合索引
mysql> alter table tuser add index idx_name_age_sex(name,age,sex);
--创建全文索引
mysql> alter table taddr add fulltext ft_addr(addr);

1. id

  • 每个 SELECT语句都会自动分配的一个唯一标识符.
  • 表示查询中操作表的顺序,有三种情况:
    -- id相同:执行顺序由上到下
    -- id不同:如果是子查询,id号会自增,id越大,优先级越高。
    -- id相同的不同的同时存在
  • id列为null的就表示这是一个结果集,不需要使用它来进行查询。

2. select_type(重要)

  • 查询类型,主要用于区别普通查询、联合查询(union、union all)、子查询等复杂查询。

simple
表示不需要union操作或者不包含子查询的简单select查询。有连接查询时,外层的查询为simple,且只有一个
primary
一个需要union操作或者含有子查询的select,位于最外层的单位查询的select_type即为primary。且只有一个
subquery
除了from字句中包含的子查询外,其他地方出现的子查询都可能是subquery
dependent subquery
与dependent union类似,表示这个subquery的查询要受到外部表查询的影响
union
union连接的两个select查询,第一个查询是PRIMARY,除了第一个表外,第二个以后的表select_type都是union
dependent union
与union一样,出现在union 或union all语句中,但是这个查询要受到外部查询的影响
union result
包含union的结果集,在union和union all语句中,因为它不需要参与查询,所以id字段为null
derived
from字句中出现的子查询,也叫做派生表,其他数据库中可能叫做内联视图或嵌套select

3. table

  • 显示的查询表名,如果查询使用了别名,那么这里显示的是别名
  • 如果不涉及对数据表的操作,那么这显示为null
  • 如果显示为尖括号括起来的就表示这个是临时表,后边的N就是执行计划中的id,表示结果来自于这个查询产生。
  • 如果是尖括号括起来的<union M,N>,与类似,也是一个临时表,表示这个结果来自于union查询的id为M,N的结果集。

4. type(重要)
依次从好到差:
system,const,eq_ref,ref,fulltext,ref_or_null,unique_subquery, index_subquery,range,index_merge,index,ALL
除了all之外,其他的type都可以使用到索引,除了index_merge之外,其他的type只可以用到一个索引
注意事项最少要索引使用到range级别。

system,表中只有一行数据或者是空表。
const,使用唯一索引或者主键,返回记录一定是1行记录的等值where条件时,通常type是const。其他数据库也叫做唯一索引扫描
eq_ref,关键字:连接字段主键或者唯一性索引。都只能匹配到后表的一行结果
ref,针对非唯一性索引,使用等值(=)查询非主键。或者是使用了最左前缀规则索引的查询。
fulltext,全文索引检索
ref_or_null,增加了null值的比较
unique_subquery,用于where中的in形式子查询,子查询返回不重复值唯一值
index_subquery,用于in形式子查询使用到了辅助索引或者in常数列表,子查询可能返回重复值,可以使用索引将子查询去重。
range,索引范围扫描,常见于使用>,<,is null,between ,in ,like等运算符的查询中。
index_merge,表示查询使用了两个以上的索引,最后取交集或者并集
index,关键字:条件是出现在索引树中的节点的。可能没有完全匹配索引。索引全表扫描
ALL, 全表扫描数据文件

5. possible_keys: 此次查询中可能选用的索引,一个或多个、
6. key : 查询真正使用到的索引
7. key_len: 处理查询的索引长度,key_len只计算where条件用到的索引长度,而排序和分组就算用到了索引,也不会计算到key_len中
8. ref

  • 如果是使用的常数等值查询,这里会显示const
  • 如果是连接查询,被驱动表的执行计划这里会显示驱动表的关联字段
  • 如果是条件使用了表达式或者函数,或者条件列发生了内部隐式转换,这里可能显示为func

9. rows: 执行计划中估算的扫描行数,不是精确值(InnoDB不是精确的值,MyISAM是精确的值,主要原因是InnoDB里面使用了MVCC并发机制)
10. Extra

  • using temporary: 使用了临时表存储中间结果,MySQL在对查询结果order by和group by时使用临时表; 临时表可以是内存临时表和磁盘临时表,执行计划中看不出来,需要查看status变量,used_tmp_table,used_tmp_disk_table才能看出来。
  • no tables used : 使用not in()形式子查询或not exists运算符的连接查询,这种叫做反连接
  • using filesort : MySQL中无法利用索引完成的排序操作称为“文件排序”
  • using index
  • using where: 存储引擎返回的记录并不是所有的都满足查询条件,需要在server层进行过滤。
  • firstmatch(tb_name): 5.6.x开始引入的优化子查询的新特性之一,常见于where字句含有in()类型的子查询。如果内表的数据量比较大,就可能出现这个
  • loosescan(m..n): 在in()类型的子查询中,子查询返回的可能有重复记录时,
    就可能出现这个
  • filtered : 5.7之后的版本默认就有这个字段,不需要使用explain extended了.这个字段表示存储引擎返回的数据在server层过滤后,剩下多少满足查询的记录数量的比
    例,注意是百分比,不是具体记录数。

参考网站
https://segmentfault.com/a/1190000008131735
https://blog.csdn.net/rewiner120/article/details/70598797

  • 索引失效分析

1.全值匹配 *
2.最佳左前缀法则 组合索引-> 带头索引不能死,中间索引不能断
3.不要在索引上做计算
4.范围条件右边的列失效
5.尽量使用覆盖索引 也就是索引列和查询列一致,减少select *
6.索引字段上不要使用不等,会导致索引失效而转向全表扫描
7.主键索引字段上不可以判断null
主键字段上不可以使用 null
索引字段上使用 is null / is not null 判断时,可使用索引
8.索引字段使用like不以通配符开头
9.索引字段字符串要加单引号
10.索引字段不要使用or 索引字段使用 or 时,会导致索引失效而转向全表扫描

总结

image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • 索引 数据库中的查询操作非常普遍,索引就是提升查找速度的一种手段 索引的类型 从数据结构角度分 1.B+索引:传统...
    一凡呀阅读 2,853评论 0 8
  • 零.索引简介 1. 索引是什么 ①MySQL官方对索引的定义是:索引(Index)是帮助MySQL高效获取数据的数...
    一条路上的咸鱼阅读 913评论 0 6
  • 索引的本质 MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。提取句子主干,...
    mysia阅读 574评论 0 1
  • 一部电影许多故事 一场救赎&诸多感动[大哭] 我们生来平凡,却并不甘愿平庸 从来就不是国产电影的座上宾,这一次却给...
    天天0925阅读 400评论 0 0
  • 上周去找朋友玩,朋友说起了前几天发生的事。 当时她骑着便携式脚踏车,在机动车道边行驶,当时后面跟着骑着电动车的外卖...
    喵喵诗茵阅读 292评论 0 2