记录Mysql索引类型,索引生效和失效场景

记录Mysql索引类型,索引生效和失效场景

创建数据表

DROP TABLE IF EXISTS staff;
CREATE TABLE staff (
	id BIGINT(22) not null auto_increment,
	name VARCHAR(22) COMMENT '姓名',
	age TINYINT(3) COMMENT '年龄',
	pos VARCHAR(22) COMMENT '职位',
	salary DOUBLE COMMENT '薪水',
	PRIMARY KEY(`id`)
)ENGINE=INNODB CHARSET=utf8;

创建索引

CREATE INDEX `multi_index` on staff(name,age,pos);

插入测试数据

在这里插入图片描述

对比执行sql语句

-- Case#1:两边都是%
EXPLAIN SELECT * FROM staff WHERE name LIKE '%Alice%';
-- 索引失效 type=all

-- Case#2:左边是%
EXPLAIN SELECT * FROM staff WHERE name LIKE '%Alice';
-- 索引失效 type=all

-- Case#3:右边是%
EXPLAIN SELECT * FROM staff WHERE name LIKE 'Alice%';
-- 索引生效 type=range

从结果可以看出:当使用like模糊匹配时,只有%写在右边索引才会生效,索引类型为type=range,即范围搜索,这是因为Mysql的最左匹配原则。

-- Case#:右边是%
EXPLAIN SELECT * FROM staff WHERE name LIKE 'Alice%';
-- type=range extra=Using where

EXPLAIN SELECT name,age,pos FROM staff WHERE name LIKE 'Alice%';
-- type=index extra=Using where; Using index

where条件相同,但是一个查询字段了是*,一个是name,age,pos,虽然索引都生效了,但是Explain的执行结果完全不同

SELECT * FROM staff WHERE name LIKE 'Alice%';做了回表查询

SELECT name,age,pos FROM staff WHERE name LIKE 'Alice%';使用了索引覆盖,再从索引文件中过滤数据(extra=Using where; Using index)

EXPLAIN SELECT name,age,pos FROM staff WHERE name LIKE 'Alice%';
-- type=index extra=Using where; Using index

EXPLAIN SELECT name,age,pos FROM staff WHERE name LIKE '%Alice%';
-- type=index extra=Using where; Using index

从上面结果可看出:当SELECT后面的字段属于索引字段范畴,后面的LIKE语句中%在哪个位置都不重要了,因为都是使用了索引覆盖,再从索引文件中过滤数据。

再来几个测试样例,可见只要查询的字段中只要包含无索引的字段,那么最终都是全表扫描,索引失效。

-- IndexCase#:查询Id
EXPLAIN SELECT id FROM staff WHERE name LIKE '%Alice%';
-- 结果:使用上了索引(因为 name 有索引,同时查询的 Id 是主键肯定也有索引)
-- type=index extra=Using where; Using index

EXPLAIN SELECT salary FROM staff WHERE name LIKE '%Alice%';
-- type=all extra=Using where; Using index

-- IndexCase#5:查询name
EXPLAIN SELECT name FROM staff WHERE name LIKE '%Alice%';
-- 结果:使用上了索引(因为查询条件和查询字段都是有索引的 name)
-- type=index extra=Using where; Using index

-- IndexCase#6:查询age
EXPLAIN SELECT age FROM staff WHERE name LIKE '%Alice%';
-- 结果:使用上了索引(因为查询条件的 name 以及查询字段的 age 都有索引)
-- type=index extra=Using where; Using index

EXPLAIN SELECT pos FROM staff WHERE name LIKE '%Alice%';
-- type=index extra=Using where; Using index

-- IndexCase#7:查询 id & name
EXPLAIN SELECT id, name FROM staff WHERE name LIKE '%Alice%';
-- 结果:使用上了索引(因为查询条件的 name 以及查询字段的 id & name 都有索引)
-- type=index extra=Using where; Using index

EXPLAIN SELECT pos,name FROM staff WHERE name LIKE '%Alice%';
-- 使用上了索引,索引顺序很重要,最左匹配原则
-- type=index extra=Using where; Using index

EXPLAIN SELECT name,age,pos FROM staff WHERE name LIKE '%Alice%';
-- type=index extra=Using where; Using index

EXPLAIN SELECT name,age,pos,salary FROM staff WHERE name LIKE '%Alice%';
-- type=all extra=Using where
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 数据量过小:当数据量过小时,使用索引并不会提高查询效率,反而会增加查询时间和资源消耗。 2. 索引列不符合最左前缀原则:最左前缀原则是指在查询时,只有使用了索引的最左前缀部分,索引才能生效。如果查询语句没有使用索引的最左前缀,那么索引就会失效。 3. LIKE查询以通配符开头:如果查询语句中使用了LIKE查询,并且通配符(%或_)出现在查询字符串的开头,那么索引就会失效。 4. 数据分布不均匀:如果索引列中的数据分布不均匀,那么索引就会失效。例如,一个表中有1000条记录,其中有900条记录的字段值为A,100条记录的字段值为B,如果查询字段值为B的记录,那么使用索引并不能提高查询效率。 5. 查询条件中使用了函数或表达式:如果查询条件中使用了函数或表达式,那么索引就会失效。因为索引是针对字段的,而函数或表达式是针对值的,所以无法使用索引优化查询。 6. 连接查询中未使用索引:如果在连接查询中,未使用连接条件中的索引列,那么索引就会失效。因为连接条件中的索引列是连接的关键,不使用索引会导致全表扫描。 7. 存在大量的NULL值:如果索引列存在大量的NULL值,那么索引就会失效。因为索引不会为NULL值建立索引,所以在查询时会导致全表扫描。 8. 数据表结构变更:如果数据表结构发生变更,如添加或删除字段,那么索引就会失效。需要重新建立索引
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值