前言

最近一直忙着处理原来老项目遗留的一些SQL优化问题,由于当初表的设计以及字段设计的问题,随着业务的增长,出现了大量的慢SQL,导致MySQL的CPU资源飙升,基于此,给大家简单分享下这些比较使用的易于学习和使用的经验。

这次的话简单说下如何防止你的索引失效。

再说之前我先根据我最近的经验说下我对索引的看法,我觉得并不是所以的表都需要去建立索引,对于一些业务数据,可能量比较大了,查询数据已经有了一点压力,那么最简单、快速的办法就是建立合适的索引,但是有些业务可能表里就没多少数据,或者表的使用频率非常不高的情况下是没必要必须要去做索引的。就像我们有些表,2年了可能就10来条数据,有索引和没索引性能方面差不多多少。

索引只是我们优化业务的一种方式,千万为了为了建索引而去建索引。

下面是我此次测试使用的一张表结构以及一些测试数据

CREATE TABLE `user` (

`id` int(5) unsigned NOT NULL AUTO_INCREMENT,

`create_time` datetime NOT NULL,

`name` varchar(5) NOT NULL,

`age` tinyint(2) unsigned zerofill NOT NULL,

`sex` char(1) NOT NULL,

`mobile` char(12) NOT NULL DEFAULT '',

`address` char(120) DEFAULT NULL,

`height` varchar(10) DEFAULT NULL,

PRIMARY KEY (`id`),

KEY `idx_createtime` (`create_time`) USING BTREE,

KEY `idx_name_age_sex` (`name`,`sex`,`age`) USING BTREE,

KEY `idx_ height` (`height`) USING BTREE,

KEY `idx_address` (`address`) USING BTREE,

KEY `idx_age` (`age`) USING BTREE

) ENGINE=InnoDB AUTO_INCREMENT=261 DEFAULT CHARSET=utf8;

INSERT INTO `bingfeng`.`user`(`id`, `create_time`, `name`, `age`, `sex`, `mobile`, `address`, `height`) VALUES (1, '2019-09-02 10:17:47', '冰峰', 22, '男', '1', '陕西省咸阳市彬县', '175');INSERT INTO `bingfeng`.`user`(`id`, `create_time`, `name`, `age`, `sex`, `mobile`, `address`, `height`) VALUES (2, '2020-09-02 10:17:47', '松子', 13, '女', '1', NULL, '180');INSERT INTO `bingfeng`.`user`(`id`, `create_time`, `name`, `age`, `sex`, `mobile`, `address`, `height`) VALUES (3, '2020-09-02 10:17:48', '蚕豆', 20, '女', '1', NULL, '180');INSERT INTO `bingfeng`.`user`(`id`, `create_time`, `name`, `age`, `sex`, `mobile`, `address`, `height`) VALUES (4, '2020-09-02 10:17:47', '冰峰', 20, '男', '17765010977', '陕西省西安市', '155');INSERT INTO `bingfeng`.`user`(`id`, `create_time`, `name`, `age`, `sex`, `mobile`, `address`, `height`) VALUES (255, '2020-09-02 10:17:47', '竹笋', 22, '男', '我测试下可以储存几个中文', NULL, '180');INSERT INTO `bingfeng`.`user`(`id`, `create_time`, `name`, `age`, `sex`, `mobile`, `address`, `height`) VALUES (256, '2020-09-03 10:17:47', '冰峰', 21, '女', '', NULL, '167');INSERT INTO `bingfeng`.`user`(`id`, `create_time`, `name`, `age`, `sex`, `mobile`, `address`, `height`) VALUES (257, '2020-09-02 10:17:47', '小红', 20, '', '', NULL, '180');INSERT INTO `bingfeng`.`user`(`id`, `create_time`, `name`, `age`, `sex`, `mobile`, `address`, `height`) VALUES (258, '2020-09-02 10:17:47', '小鹏', 20, '', '', NULL, '188');INSERT INTO `bingfeng`.`user`(`id`, `create_time`, `name`, `age`, `sex`, `mobile`, `address`, `height`) VALUES (259, '2020-09-02 10:17:47', '张三', 20, '', '', NULL, '180');INSERT INTO `bingfeng`.`user`(`id`, `create_time`, `name`, `age`, `sex`, `mobile`, `address`, `height`) VALUES (260, '2020-09-02 10:17:47', '李四', 22, '', '', NULL, '165');

单个索引

1、使用!= 或者 <> 导致索引失效

SELECT * FROM `user` WHERE `name` != '冰峰';

我们给name字段建立了索引,但是如果!= 或者 <> 这种都会导致索引失效,进行全表扫描,所以如果数据量大的话,谨慎使用

可以通过分析SQL看到,type类型是ALL,扫描了10行数据,进行了全表扫描。<>也是同样的结果。

2、类型不一致导致的索引失效

在说这个之前,一定要说一下设计表字段的时候,千万、一定、必须要保持字段类型的一致性,啥意思?比如user表的id是int自增,到了用户的账户表user_id这个字段,一定、必须也是int类型,千万不要写成varchar、char什么的骚操作。

SELECT * FROM `user` WHERE height= 175;

这个SQL诸位一定要看清楚,height表字段类型是varchar,但是我查询的时候使用了数字类型,因为这个中间存在一个隐式的类型转换,所以就会导致索引失效,进行全表扫描。

现在明白我为啥说设计字段的时候一定要保持类型的一致性了不,如果你不保证一致性,一个int一个varchar,在进行多表联合查询(eg: 1 = '1')必然走不了索引。

遇到这样的表,里面有几千万数据,改又不能改,那种痛可能你们暂时还体会。

少年们,切记,切记。

3、函数导致的索引失效

SELECT * FROM `user` WHERE DATE(create_time) = '2020-09-03';

如果你的索引字段使用了索引,对不起,他是真的不走索引的。

4、运算符导致的索引失效

SELECT * FROM `user` WHERE age - 1 = 20;

如果你对列进行了(+,-,*,/,!), 那么都将不会走索引。

5、OR引起的索引失效

SELECT * FROM `user` WHERE `name` = '张三' OR height = '175';

OR导致索引是在特定情况下的,并不是所有的OR都是使索引失效,如果OR连接的是同一个字段,那么索引不会失效,反之索引失效。

6、模糊搜索导致的索引失效

SELECT * FROM `user` WHERE `name` LIKE '%冰';

这个我相信大家都明白,模糊搜索如果你前缀也进行模糊搜索,那么不会走索引。

7、NOT IN、NOT EXISTS导致索引失效

SELECT s.* FROM `user` s WHERE NOT EXISTS (SELECT * FROM `user` u WHERE u.name = s.`name` AND u.`name` = '冰峰')

SELECT * FROM `user` WHERE `name` NOT IN ('冰峰');

这两种用法,也将使索引失效。但是NOT IN 还是走索引的,千万不要误解为 IN 全部是不走索引的。我之前就有误解(丢人了...)。

8、IS NULL不走索引,IS NOT NULL走索引

SELECT * FROM `user` WHERE address IS NULL

不走索引。

SELECT * FROM `user` WHERE address IS NOT NULL;

走索引。

根据这个情况,建议大家这设计字段的时候,如果没有必要的要求必须为NULL,那么最好给个默认值空字符串,这可以解决很多后续的麻烦(有深刻的体验)。

符合索引

1、最左匹配原则

EXPLAIN SELECT * FROM `user` WHERE sex = '男';

EXPLAIN SELECT * FROM `user` WHERE name = '冰峰' AND sex = '男';

测试之前,删除其他的单列索引。

啥叫最左匹配原则,就是对于符合索引来说,它的一个索引的顺序是从左往右依次进行比较的,像第二个查询语句,name走索引,接下来回去找age,结果条件中没有age那么后面的sex也将不走索引。

注意:

SELECT * FROM `user` WHERE sex = '男' AND age = 22 AND `name` = '冰峰';

可能有些搬砖工可能跟我最开始有个误解,我们的索引顺序明明是name、sex、age,你现在的查询顺序是sex、age、name,这肯定不走索引啊,你要是自己没测试过,也有这种不成熟的想法,那跟我一样还是太年轻了,它其实跟顺序是没有任何关系的,因为mysql的底层会帮我们做一个优化,它会把你的SQL优化为它认为一个效率最高的样子进行执行。所以千万不要有这种误解。

2、如果使用了!=会导致后面的索引全部失效

SELECT * FROM `user` WHERE sex = '男' AND `name` != '冰峰' AND age = 22;

我们在name字段使用了 != ,由于name字段是最左边的一个字段,根据最左匹配原则,如果name不走索引,后面的字段也将不走索引。

关于符合索引导致索引失效的情况能说的目前就这两种,其实我觉得对于符合索引来说,重要的是如何建立高效的索引,千万不能说我用到那个字段我就去建立一个单独的索引,不是就可以全局用了嘛。这样是可以,但是这样并没有符合索引高效,所以为了成为高级的搬砖工,我们还是要继续学习,如何创建高效的索引。

总结

到此这篇关于导致MySQL索引失效的一些常见写法的文章就介绍到这了,更多相关MySQL索引失效的常见写法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

like左匹配索引失效_导致MySQL索引失效的一些常见写法总结相关推荐

  1. mysql索引失效_导致MySQL索引失效的几种常见写法

    最近一直忙着处理原来老项目遗留的一些SQL优化问题,由于当初表的设计以及字段设计的问题,随着业务的增长,出现了大量的慢SQL,导致MySQL的CPU资源飙升,基于此,给大家简单分享下这些比较使用的易于 ...

  2. mysql group 索引失效_介绍mysql索引失效的情况

    mysql视频教程栏目索引失效的情况. 索引对于MySQL而言,是非常重要的篇章.索引知识点也巨多,要想掌握透彻,需要逐个知识点一一击破,今天来先来聊聊哪些情况下会导致索引失效. 图片总结版 相关免费 ...

  3. mysql的覆盖索引原理_「Mysql索引原理(七)」覆盖索引

    通常大家都会根据查询的WHERE条件来创建合适的索引,不过这只是索引优化的一个方面.设计优秀的索引应该考虑到整个查询,而不单单是WHERE条件部分.索引确实是一种查找数据的高效方式,但是MySQL也可 ...

  4. mysql设置索引长度_修改Mysql索引长度限制

    mysql 索引过长1071-max key length is 767 byte 问题 create table: Specified key was too long; max key lengt ...

  5. Mysql 唯一索引长度_关于mysql索引长度的相关内容总结

    MySQL优化之-索引具体代码分析:索引是在存储引擎中实现的,因此每种存储引擎的索引都不一定完全相同,并且每种存储引擎也不一定支持所有索引类型.根据存储引擎定义每个表的最大索引数和最大索引长度.所有存 ...

  6. 什么情况会导致 MySQL 索引失效?

    为了验证 MySQL 中哪些情况下会导致索引失效,我们可以借助 explain 执行计划来分析索引失效的具体场景. explain 使用如下,只需要在查询的 SQL 前面添加上 explain 关键字 ...

  7. mysql 按时间累计计算_精通MySQL索引背后的数据结构及算法原理

    本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,mysql支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree ...

  8. mysql索引_mysql系列:深入理解mysql 索引特性(屡试不爽的mysql索引总结)

    原标题:mysql系列:深入理解mysql 索引特性(屡试不爽的mysql索引总结) mysql为什么使用B+ Tree索引,不使用B- Tree索引? 索引顺序如何生效? 什么是覆盖索引? orde ...

  9. 数据库索引原理,及MySQL索引类型

    原文:数据库索引原理,及MySQL索引类型 - weixin_42181824的博客 - CSDN博客  https://blog.csdn.net/weixin_42181824/article/d ...

最新文章

  1. Linux 下文件系统权限控制及管理
  2. 学python有哪些书推荐-学python看什么书好?求推荐
  3. 安装modelsim
  4. GeosparkViz 可视化
  5. 分区格式化并给用户设定配额
  6. COVID-19和世界幸福报告数据告诉我们什么?
  7. python判断是相邻数字,检查Python中相邻数字的绝对差之和是否为素数
  8. android中的通信机制总结
  9. matlab半波整流怎么做,基于Matlab的单相半波可控整流电路的设计与仿真.doc
  10. CAD中怎么配置灭火器?
  11. html5在线+网站,15个在线HTML5网页设计工具
  12. React组件通信-父子组件间的通信
  13. 凸优化1——仿射集、凸集、锥
  14. Kruise Rollout:灵活可插拔的渐进式发布框架
  15. Flex之AdvancedDataGrid用法
  16. 基于STM32单片机的跑步机心率检测proteus仿真原理图PCB
  17. 〖大前端 - 基础入门三大核心之CSS篇③〗- CSS选择器之复合选择器与伪类
  18. 身份认证的动态密码器解决方案
  19. 舆情舆论监测措施与方法
  20. JAVA网络编程个人笔记 第4章 inet地址

热门文章

  1. 云架构的基础转变会带来哪些变化?
  2. Juint整合Log4j
  3. iOS开发网络篇—网络请求(HTTP协议)小结(转)
  4. HDU 2502 月之数(简单递推)
  5. 活动安排问题--贪心算法
  6. 甜、酸、苦、辣、咸与健康
  7. 多媒体调度系统如何实现对水库大坝的防洪调度
  8. VB中Unicode vs Ansi-From alpsong(阿尔卑斯之歌)
  9. Go 语言范围(Range)
  10. 解决服务器上 w3wp.exe 和 sqlservr.exe 的内存占用率居高不下的方案