MySQL索引失效总结

一、准备工作

  • 创建一张表 t_index ,脚本如下:
CREATE TABLE `t_index` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '表记录标识号,数据库主键,不用于实际业务',
  `key1` varchar(32) COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT '字段1',
  `key2` varchar(64) COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT '字段2',
  `key3` varchar(64) COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT '字段3',
  `del_flag` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '删除标志。0未删除,1删除。',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '记录修改时间',
  PRIMARY KEY (`id`),
  KEY `idx_create_time` (`create_time`),
  KEY `idx_update_time` (`update_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='索引表';

二、针对普通索引,如下场景会导致查询走全表查询,不走索引

1.准备工作
  • 在字段 key1 上创建索引,脚本如下:
ALTER TABLE `t_index` ADD INDEX idx_key1(key1);
  • 先看下正常走索引的查询脚本
SELECT * FROM `t_index` WHERE key1 = '1';
  • 查看执行计划
EXPLAIN SELECT * FROM `t_index` WHERE key1 = '1';
  • 结果显示走索引查询,如下图
    在这里插入图片描述
2.查询条件使用不等式
  • 查询脚本
SELECT * FROM `t_index` WHERE key1 <> '1';
  • 查看执行计划,结果显示全表扫描,如下图
    在这里插入图片描述

  • 总结:不等式 <>!= 会导致索引失效

3.查询条件类型不一致
  • 查询脚本
SELECT * FROM `t_index` WHERE key1 = 1;
  • 查看执行计划,结果显示全表扫描,如下图
    在这里插入图片描述

  • 总结:字段 key1 为字符串,传入的值为数字类型,会导致索引失效

4.查询条件使用函数计算
  • 查询脚本
SELECT * FROM `t_index` WHERE key1 + 1 = 1;
SELECT * FROM `t_index` WHERE CHAR_LENGTH(key1) = 1;
  • 查看执行计划,结果显示全表扫描,如下图
    在这里插入图片描述

  • 总结:函数计算 x+1x-1CHAR_LENGTH(x) 等会导致索引失效

5.模糊查询
  • 查询脚本
SELECT * FROM `t_index` WHERE key1 LIKE  '3';
SELECT * FROM `t_index` WHERE key1 LIKE  '%3';
SELECT * FROM `t_index` WHERE key1 LIKE  '3%';
  • 查看执行计划,如下图
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 总结:模糊查询查询条件前通配会导致索引失效,后通配会走索引

三、针对复合索引,如下场景会导致查询走全表查询,不走索引

1.准备工作
  • 删除刚才的索引,在字段 key1, key2, key3 上创建复合索引,脚本如下:
DROP INDEX idx_key1 ON `t_index`;
ALTER TABLE `t_index` ADD INDEX idx_key123(key1, key2, key3);
  • 先看下正常走索引的查询脚本
SELECT * FROM `t_index` WHERE key1 = '1' AND key2 = '2' AND key3 = '3';
  • 查看执行计划
EXPLAIN SELECT * FROM `t_index` WHERE key1 = '1' AND key2 = '2' AND key3 = '3';
  • 结果显示走索引查询,如下图
    在这里插入图片描述
2.查询条件使用不等式
  • 查询脚本,只要有一个条件含有不等式,都不会走索引
SELECT * FROM `t_index` WHERE key1 <> '1' AND key2 = '2' AND key3 = '3';
SELECT * FROM `t_index` WHERE key1 = '1' AND key2 <> '2' AND key3 = '3';
SELECT * FROM `t_index` WHERE key1 = '1' AND key2 = '2' AND key3 <> '3';
  • 查看执行计划,结果显示全表扫描,三种情况结果一样,如下图
    在这里插入图片描述

  • 总结:逻辑同普通索引

3.查询条件类型不一致
  • 查询脚本
SELECT * FROM `t_index` WHERE key1 = 1 AND key2 = '2' AND key3 = '3';
SELECT * FROM `t_index` WHERE key1 = '1' AND key2 = 2 AND key3 = '3';
SELECT * FROM `t_index` WHERE key1 = '1' AND key2 = '2' AND key3 = 3;
  • 查看执行计划,结果显示(第一个参数类型不一致走全表扫描,第二个参数类型不一致,索引仅仅能使用第一列,第三个参数类型不一致,索引能使用前两列),如下图
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 总结:从第一个查询条件开始,第N个参数类型不一致,索引能使用前N-1列

4.查询条件使用函数计算
  • 查询脚本
SELECT * FROM `t_index` WHERE key1 + 1 = '1' AND key2 = '2' AND key3 = '3';
SELECT * FROM `t_index` WHERE key1 = '1' AND key2 + 1 = '2' AND key3 = '3';
SELECT * FROM `t_index` WHERE key1 = '1' AND key2 = '2' AND key3 + 1 = '3';
  • 查看执行计划,结果同上(第一个参数类型不一致走全表扫描,第二个参数类型不一致,索引仅仅能使用第一列,第三个参数类型不一致,索引能使用前两列),如下图
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 总结:逻辑同上

5.不使用索引首列当查询条件
  • 查询脚本
SELECT * FROM `t_index` WHERE key2 = '2' AND key3 = '3';
SELECT * FROM `t_index` WHERE key2 = '2';
SELECT * FROM `t_index` WHERE key3 = '3';
  • 查看执行计划,结果显示(都不会走索引),三种情况结果一样,如下图
    在这里插入图片描述

  • 总结:查询条件不使用复合索引的首列,均会导致索引失效


本文完。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 是的,在 MySQL 中,如果在 WHERE 子句中使用函数处理列的值,则可能会导致索引失效。这是因为当使用函数处理列的值时,MySQL 将无法使用索引进行快速查找。 例如,如果在 WHERE 子句中使用 LOWER() 函数来搜索小写字符串,则 MySQL 将无法使用索引进行查找,因为索引中的值是大写的。 因此,在使用 MySQL 时,应尽量避免在 WHERE 子句中使用函数处理列的值,以便使用索引进行优化查询。 ### 回答2: 在MySQL中,使用函数对字段进行操作会导致索引失效是有可能的。这是因为索引是建立在原始字段上的,当我们在查询中对字段使用函数时,MySQL必须对每个记录进行计算,以获取函数的结果,而不是直接使用索引。这样就会导致MySQL无法有效地利用索引来加速查询的过程,从而降低了查询性能。 举个例子,如果我们有一个名为"birthday"的字段,并在该字段上建立了索引,将其定义为DATE类型。如果我们在查询中使用了函数DATE()来提取birthday字段的日期,就会导致索引失效MySQL将无法直接使用索引来优化查询,而需要对每条记录进行日期计算。 那么如何避免这种情况呢?一种方法是尽量避免对字段使用函数,如果可能的话,应该在程序中对数据进行预处理,将计算移至程序中进行,而不是在查询中使用函数。另外,可以考虑对需要用到的字段建立更为常用的索引,以提高查询性能。 总结来说,使用函数可能会导致MySQL索引失效,因为函数会对每个记录进行计算,而无法直接使用索引来加速查询。为了避免这种情况,应尽量避免使用函数,如果需要使用函数,可以考虑在程序中进行预处理,或者对需要的字段建立更合适的索引。 ### 回答3: 在MySQL中,使用函数可能会导致索引失效的情况是存在的。 当我们在查询中使用函数来对某列进行处理时,例如使用函数对列进行计算、转换、截取等操作,MySQL优化器无法利用已经创建的索引来加速查询。这是因为函数会修改列的值或者将其转化为不同的数据类型,导致索引无法正确地匹配或者无法利用索引的有序性。 例如,我们有一个名为age的列,并且对其创建了一个B-tree索引。如果我们在查询中使用函数对age列进行计算,如SELECT * FROM table WHERE SQRT(age) > 10,那么MySQL无法对SQRT(age)这个表达式进行优化,无法利用age的索引,会导致索引失效。 另外,对于字符串类型的列,使用函数进行截取或者转换操作也会导致索引失效。因为函数对字符串的处理会导致索引无法正确地进行匹配,从而无法利用索引加速查询。 为了避免这种情况,可以考虑在实际存储数据时对需要进行函数处理的列进行预处理,将处理后的结果存储在新列中,并对新列创建索引。这样在查询时就可以直接使用新列的索引,避免函数导致的索引失效。 综上所述,MySQL中使用函数可能导致索引失效,这时需要注意对需要处理的列进行预处理或者重新设计查询语句,以避免影响查询性能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值