美文网首页
简介mysql之索引

简介mysql之索引

作者: 温岭夹糕 | 来源:发表于2020-04-06 10:41 被阅读0次

思考

1.索引的作用是什么?

2.索引的种类有哪些?

3.什么是回表/索引覆盖/索引下推/最左前缀原则?


问题1:索引的作用?

提高数据库的查询效率,就像我们上学在查字典一样,索引就给我们提供了数据库(字典)的目录功能

问题2:索引的种类有哪些?

什么是索引?Mysql目前主要的几种索引类型_数据库_liutong123987的专栏-CSDN博客

简单概括就是:普通/唯一/主键/组合/全文索引

其中唯一和主键的两者都是要求列值唯一,区别是主键索引要求列值不能为NULL,且只能有一个主键索引

全文索引是MyISAM特有的

问题3:如何设置索引?

1.创建表时

主键索引:指定PRIMARY KEY如

create table T(

c INT PRIMARY KEY );

create table T(

c INT NOT NULL,

PRIMARY KEY (C) );

普通索引:INDEX显示指明

create table T( 

c INT PRIMARY KEY,

c1 INT NOT NULL,

INDEX (c1) );

唯一索引:UNIQUE显示指明同理如上

全文索引FULLTEXT显示指明

2.创建表之后

ALTER TABLE 表名 ADD 索引类型 (列名)

删除索引

ALTER TABLE 表名 DROP 索引类型 列名

-显示索引

desc 表名

show index from 表名

问题4:索引的类型有哪些?

根据索引的实现方式不同我们可以划分索引类型

常见的有

1.HASH(哈希表)

即key-value形式,值(value)通过一定的函数或数学方式转换后会生成一串哈希值(key),(哈希表的时间复杂度为O1)但还是会出现多个值通过换算后会生成同一个哈希值的情况即(不同value,相同key)。

解决方法就是同key时再拉出一个链表

2.有序数组

有序数组的查询时间复杂度为O(logn)(二分法)

3.BTREE搜索树

关于InnoDB的索引类型

通过show index from 表名(前提需要给列添加索引)

我们可以观察到innodb引擎使用B+树来存储索引数据,且每一个索引对应了一颗B+树

在innodb中,主键索引被称为聚簇索引,非主键索引被称为二级索引     ----《mysql实战45讲》

因此有没有用到索引就是有没有用到b+树来进行快速查找

问题5:主键索引和普通索引的区别?

如上表假设主键索引为ID,c为普通索引

在执行select * from T where ID=1时,只需搜索ID一颗B+树;

在执行 select * from T where c=1时,需要先搜索c这颗B+树的索引并获取ID值,再根据ID搜索一次ID的B+树,即涉及两颗树的搜索;

也就是说二级索引的搜索会多一次主键树的扫描,因此尽量使用主键查询

问题6:一定要将需要查询的主要数据做主键?

理清一个概念先,在B+树中

主键索引的叶子节点为整行数据

非主键索引的叶子节点为主键的值

主键越小,普通索引的叶子节点越小,普通索引占空间也越小,所以从存储角度讲自增主键更合理

问题7:什么是回表?

回几次表可以理解为要额外查询几颗树,以下表为例 

create table A( 

id int(10) unsigned not null auto_increment comment '主键ID', 

name varchar(20) comment '普通值', 

age int(2) unsigned comment '普通索引',

primary key(id) using BTREE,

key age (age) using BTREE )ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

插入数据

insert into A (name,age) values ('1',1);

insert into A (name,age) values ('2',2);

insert into A (name,age) values ('3',3);

insert into A (name,age) values ('4',4);

insert into A (name,age) values ('5',5);

sql语句如下 select id,name from A where age=2

1.因为age为索引,先扫描了一遍age的B+树,拿到主键 2.再扫描一遍主键的B+树,获取name 这就是回表

再复杂点between? select * from A where age between 2 and 4; 

1.先查找age树,找到age=2,得id=2 

2.回表一次查找id=2对应的数据 3.查找age树,找到age=3,得id=3 

4.回表第二次查找id=3对应的数据 

5.查找age树,找到age=4,得id=4 

6.回表第三次查找id=4对应的数据 5.查找age树,找到age=6,不满足,循环结束

所谓的回表查询,即先定位主键值,再根据主键值定位行记录,性能相对于只扫描一遍聚集索引树的性能要低一些

问题7:什么是索引覆盖?

只需要在一棵索引树上就能获取SQL所需的所有列数据,无需回表 select id from A where age=2 因为age的B+树上记录的就是主键ID的值 (执行 explain select id from A where age=2 观察到extra using index 即使用了索引,进行了索引覆盖 同理聚合查询 explain select count(age) from A; )

利用索引覆盖优化between select id from A where age between 2 and 4;

问题8:什么是最左前缀原则?

最左前缀的建立就涉及到了联合索引的建立顺序 比如有联合索引 

key name_and_age (age,name)

 select * from table where name=1 和 select * from table where age=1都会用到索引 (根据mysql的原理,只要是索引或者满足索引的一部分就可以使用index方式扫描) 但是name=1效率不高! 注意:复合索引 什么情况下才能真正被调用?最左侧的索引字段先进行了等值匹配,之后的字段变得有序时,才会用到这个复合索引。简单说。就是复合索引的字段最好有有序的才会确保用到它。 也就是说 建立了联合索引 (a,b,c)就相当于建立了(a),(a,b),(a,b,c)三个索引,从形式上看就是索引向左侧聚集,所以叫做最左原则,因此最常用的条件应该放到联合索引的组左侧。

联合索引失效的原因:联合索引 (a,b)的索引B+树是根据左侧a值的顺序来依次构造树节点的(B+树是一颗按照一定规律有序排列节点的树),也就是说虽然这颗树的叶子节点的键是(a,b)的值,但是按序遍历这颗树时,a的顺序是可以保证的,但是b是在a相同的情况下才保证是有序的,假设以下是联合索引前序遍历结果

(1,1) (1,2) (2,1) (3,1) (3,2)

a的值依次为1,1,2,3,3 这里看到是有序的

b的值依次为1,2,1,1,2 虽然a相同是有序的,但是按需遍历时却是无序的

select * from A where a=1 and b=2

a有序排列我们可以在找到a的基础上利用二分快速查找的b(二分查找的前提是有序的)

select * from A where  b=2

在没有a的情况下是无序的,也就是说这个索引树存在和没存在都是没区别的,因此联合索引失效!

根据这个原理我们也可以分析为啥select * from A where a>1 and b=2联合索引会失效:因为虽然我们可以利用a>1快速确定字节点,但是a>1的子节点上b的排布不一定是有序的如

(2,1) (2,2)  (3,1)

这个时候也需要全部遍历(select * from A where a=1 and b>2则不同)

带头索引不能死,中间索引不能断!

问题9:什么是索引下推?

(5.6版本之后,更多也是针对联合索引) 可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数

索引下推(5.6版本+)_憧憬的专栏-CSDN博客_索引下推

什么时候索引失效

如下创建表并插入数据(name为普通索引,sex和age为联合索引)

create table A( id int(10) unsigned not null auto_increment, name varchar(20), age int(10),sex int(2), pimaryrimary key(id) using BTREE, key name(name),key age_sex(age,sex))engine=innodb;

insert into A (name,age,sex) values ('z3',5,1);

insert into A (name,age,sex) values ('z2',1,1);

insert into A (name,age,sex) values ('w3',1,0);

insert into A (name,age,sex) values ('l4',8,1);

1.有or时会进行全表扫描

explain select * from A where id=1 or age=1\G

这里我们观察type值为ALL,表示走了全文搜索,rows为4(一共4条)

关于or走不走索引一直有不同的见解,但是相同点是当or查询两侧没有一列是主键时,肯定走全表扫描,当有一列为主键时,mysql会自己判断走索引还是扫描全表(这根据数据量来判断,我这里没法验证)

2.没使用最左前缀原则(包括乱用!=,<>,or)

这里我们看到遵循和不遵循结果是相差很多的

3.like查询以%开头

原理:字符串在b+树中一般按字母顺序去排序,在第一个相同的情况下拿第二个去比较

4.存在数据类型的隐式转换

5.where字句存在数学运算(或使用函数)

6.如果mysql估计使用全表扫描要比使用索引快,则不使用索引

比如数据量少的表

更多情况参考MySQL高级 之 索引失效与优化详解_wuseyukui的专栏-CSDN博客

什么情况不推荐使用索引

1.数据唯一性差的字段(取值结果只有几个)

2.平凡更新的字段

3.不在where字句中出现的字段

4.where 子句里对索引列使用不等于(<>),使用索引效果一般

相关文章

  • MySQL索引及查询优化书目录

    MySQL索引的原理之索引目的 MySQL索引的原理之索引原理 MySQL索引的原理之索引的类型 MySQL索引的...

  • 简介mysql之索引

    问题1:索引的作用? 提高数据库的查询效率,就像我们上学在查字典一样,索引就给我们提供了数据库(字典)的目录功能 ...

  • MySQL的索引原理与查询优化

    一、MySQL 索引简介 1、 MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL...

  • 关于MySQL索引的几件小事

    零.索引简介 1. 索引是什么 ①MySQL官方对索引的定义是:索引(Index)是帮助MySQL高效获取数据的数...

  • JavaEE进阶知识学习-----Mysql数据库--索引基础知

    3.索引简介 索引是什么 官方定义:索引(mysql)是帮助MySql高效获取数据的数据结构,可以说索引的本质:索...

  • 重新学习Mysql数据库4:Mysql索引实现原理

    MySQL索引类型 一、简介 MySQL目前主要有以下几种索引类型:1.普通索引2.唯一索引3.主键索引4.组合索...

  • mysql索引简介

    索引是什么 mysql官方定义: 索引(index)是帮助mysql高效获取数据的数据结构。 所以索引的本质:索引...

  • MySQL索引简介

    索引是什么? MySQL官方对索引的定义为:索引是帮助MySQL高效获取数据的数据结构;索引是提高查询速度的最重要...

  • MySQL索引简介

    索引 即特定的MySQL字段进行一些特定的算法排序,帮助MySQL高效获取数据的数据结构 MySQL数据库支持多种...

  • MySQL索引简介

    索引的分类 1. 普通索引和唯一索引 普通索引是mysql 中的基本索引类型,允许在自定义索引的列中插入重复值和空...

网友评论

      本文标题:简介mysql之索引

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