关于java:MySQL查询为什么没走索引这篇文章带你全面解析

40次阅读

共计 1506 个字符,预计需要花费 4 分钟才能阅读完成。

工作中,常常遇到这样的问题,我明明在 MySQL 表下面加了索引,为什么执行 SQL 查问的时候却没有用到索引?

同一条 SQL 有时候查问用到了索引,有时候却没用到索引,这是咋回事?

起因可能是索引生效了,生效的起因有以下几种,看你有没有踩过相似的坑?

1. 数据筹备:

有这么一张用户表,在 name 字段上建个索引:

CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(255) DEFAULT NULL COMMENT '姓名',
  `age` int DEFAULT NULL COMMENT '年龄',
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`)
) ENGINE=InnoDB COMMENT='用户表';

2. Explain 详解:

想要查看一条 SQL 是否用到索引?用到了哪种类型的索引?

能够应用 explain 关键字,查看 SQL 执行打算。例如:

explain select * from user where id=1;

能够看到 type=const,示意应用了主键索引。

explain 的所有 type 类型如下:

3. 生效起因

1. 数据类型隐式转换

name 字段是 varchar 类型,如果咱们应用数据类型查问,就会产生数据类型转换,尽管不会报错,然而无奈用到索引。

explain select * from user where name='一灯';

explain select * from user where name=18;

2. 含糊查问 like 以 % 结尾

explain select * from user where name like '张 %';

explain select * from user where name like '% 张';

3. or 前后没有同时应用索引

尽管 name 字段上加了索引,然而 age 字段没有索引,应用 or 的时候会全表扫描。

# or 前后没有同时应用索引,导致全表扫描
explain select * from user where name='一灯' or age=18;

4. 联结索引,没有应用第一列索引

如果咱们在(name,age)上,建设联结索引,然而查问条件中只用到了 age 字段,也是无奈用到索引的。

应用联结索引,必须遵循最左匹配准则,首先应用第一列字段,而后应用第二列字段。

CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(255) DEFAULT NULL COMMENT '姓名',
  `age` int DEFAULT NULL COMMENT '年龄',
  PRIMARY KEY (`id`),
  KEY `idx_name_age` (`name`,`age`)
) ENGINE=InnoDB COMMENT='用户表';

5. 在索引字段进行计算操作

如果咱们在索引列进行了计算操作,也是无奈用到索引的。

# 在主键索引上进行计算操作,导致全表扫描
explain select * from user where id+1=2;

6. 在索引字段字段上应用函数

如果咱们在索引列应用函数,也是无奈用到索引的。

7. 优化器选错索引

同一条 SQL 有时候查问用到了索引,有时候却没用到索引,这是咋回事?

这可能是优化器抉择的后果,会依据表中数据量抉择是否应用索引。

当表中大部分 name 都是一灯,这时候用 name=’ 一灯 ’ 做查问,还会不会用到索引呢?

索引优化器会认为,用索引还不如全表扫描来得快,罗唆不必索引了。

当然咱们认为优化器优化的不对,也能够应用 force index 强制应用索引。

知识点总结:

文章继续更新,能够微信搜一搜「一灯架构」第一工夫浏览更多技术干货。

正文完
 0