MySQL的索引

目录

概念

使用场景

相关语法

查看索引

新增索引

删除索引

使用指定索引

强制使用指定索引

使用规则

extra字段存在的值

最左前缀法则

索引失效情况

覆盖索引

前缀索引

单列索引和联合索引

设计原则


概念

用于提高查询效率的数据结构,在默认的存储引擎中采取的数据结构为B+tree 创建索引虽会提高查询效率 但是会提高内存空间 是一种空间换时间的优化方式

使用场景

大量数据以及高频率查询的情况下,可以对该表的字段创建索引,以此达到查询优化的效果

相关语法

查看索引

select index from tableName;

新增索引

create index [unique | fulltext] index indexName on tableName (columnName1,...); 
​
-- 当前语法可以创建单列索引 填写多个字段后即可构建多列索引

删除索引

drop index indexName on tableName;

使用指定索引

select * from tableName use index(indexName) where condition;
​
//indexName 表示索引的名称 condition表示条件
这种人为干扰的情况下一般出现在查询字段中即存在于联合索引中 同时也单独具备一个单列索引
这种时候如果只有一个字段的话 就可以认为干涉的使用单列索引

强制使用指定索引

select * from tableName force index(indexName) where condition;
​
//同上 但是为强制使用

使用规则

extra字段存在的值

extra字段是通过explain关键字查询SQL语句的索引使用情况返回的表的字段

#### NULL: 没有用到额外的附加条件
​
#### Using filesort:查询语句中包含了oder by语句,索引无法完成排序,数据量小的时候在内存中完成排序,否者在磁盘中完成排序。
​
#### Using temporary:使用到了临时表。
​
#### Using Index:使用覆盖索引进行数据返回(Innodb引擎才存在),不会进行回表查找。
​
#### Using Where:查询语句中存在where范围查找,会回表查找数据。
​
#### Using Where Using Index:覆盖索引中存在范围查找,但是也不会进行回表,直接在索引上就能拿到数据。
​
#### Using Index Condition:跟Using Where Using Index有一些差别,它的查找用到了联合索引,查找的数据有不在索引中的字段,所以会进行回表查找数据。

最左前缀法则

最左前缀法则在联合索引中会出现,当使用联合索引时 必须确保联合索引的最左字段会被使用 否则索引失效
如果跳过了某一列 索引将部分失效
​
联合索引的创建也将依照最左前缀法则去构建
​
最左前缀法则只要确保在执行SQL语句的时候条件中包含最左字段即可 这和最左字段在条件中的所在顺序没有关系
假设我创建了一个联合索引 该联合索引的字段从左到右为phone name age;
​

select phone,name from tb_user where phone='17812345689' and name = '张三';
​
那么如果返回的列中都包含在索引中的话,那么该语句满足联合索引的最左前缀法则 且不会触发回表查询

注意

当联合索引的最左字段使用了like语句 无论是前部模糊还是尾部模糊 都有几率触发全表查询

可以通过在select 前面添加explain关键字查看该SQL语句的索引使用情况 如果在extra该列中出现了using where

那么就表示该语句中使用了全表扫描

explain select phone,name from tb_user where phone like '178123%' and name = '张三';

索引失效情况

1.联合索引不满足最左前缀法则

2.使用运算符操作索引字段 (这将导致和B+tree树的不匹配 从而无法触发索引)

3.索引字段为字符串类型 在操作的时候不加引号

4.索引字段使用模糊查询 但是采取的是前部模糊查询 而非尾部模糊查询 前部则索引失效 尾部则不然

5.使用or进行条件筛选,or的前面使用了索引字段 而后面没有使用 则索引失效

6.如果MySQL的评估表示全表扫描的效率高于索引 那么就不会使用索引

or的索引失效情况
​

select * from tb_user where id = 2 or age =23;
​
//在该语句中id为聚集索引 而age为联合索引 联合索引需要遵守最左前缀法则 而age非最左字段 所以单独使用不具备索引的条件 也就是说在上述的SQL语句中只有id的聚集索引被使用了 所引整条SQL语句的索引调用失效

覆盖索引

所谓覆盖索引就是尽量避免select *的情况

也就是说最终的返回字段不是 * 而是索引中的字段 并且返回的字段在索引中全部具有 这样就会避免回表查询 提高查询效率

假设我创建了一个联合 从左至右为phone name age
select id,phone,name,age from tb_user where id=20;
​
//这里就通过id这个聚集索引完成了SQL查询 通过explain关键字即可查出该语句的索引执行情况为null 即不触发回表查询

前缀索引

当字段类型为字符串类型的时候,如果直接使用该字段创建索引的话,那么就将占用大量的磁盘空间,会占用大量的内存空间 严重影响查询效率。此时就可以使用前缀索引,即只存储一部分前缀作为索引

前缀索引的创建语法

create index indexName on tableNam(columnName(n));
​
//n表示截取的前缀长度

前缀长度的选择

select count(distinct substring(column,start,end)) / count(*) from tableName;
​
//column 表示需要设置前缀索引的字段
//start 表示截取的的起始值
//end 表示截取的长度
​
当得出的值为1或者最接近1则该start和len的截取范围的内容是最佳的前缀索引

单列索引和联合索引

单列索引:即一个索引只包含单个列

联合索引:即一个索引包含了多个列

在业务场景中,如果存在多个查询条件,建议建立联合索引 以此规避回表查询。

联合索引不仅可以是联合默认索引 也可以是联合唯一索引(unique)

设计原则

1.针对数据量较大,且查询操作比较频繁的表建立索引

2.针对于常作为查询条件(where)、排序(order by)、分组(group by)操作的字段建立索引

3.尽量选择区分度高的列作为索引(例如身份证号 手机号等),尽量建立唯一索引,区分度较高,使用索引的效率较高

4.如果是字符串类型的字段,字段的长度较长,可以针对于字段的特点,建立前缀索引

5.尽量使用联合索引,减少单列索引,查询时,联合索引很多时候可以覆盖索引,节省存储空间,避免回表,提高查询效率

6.要控制索引的数量,索引并不是多多益善,索引越多,维护索引结构的代价也就越大,会影响增删改的效率

7.如果索引列不能存储null值,请在创建表时使用NOT NULL约束它 当优化器知道每列时候包含NULL值时,它可以更好的确定哪个索引的效率最高

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值