最近一直忙着处理原来老项目遗留的一些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不走索引,后面的字段也将不走索引。


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

以上,便是今天的分享,希望大家喜欢,觉得内容不错的,欢迎点击「在看」支持,谢谢各位

更多精彩:

图解 Java 垃圾回收机制,写得非常好!

为什么禁止你在代码中使用"User"单词?

牛逼!一个故事讲清楚 NIO 了

扔掉 Postman ,试试 IntelliJ IDEA 自带的插件!

Elasticsearch 在互联网公司大量真实的应用案例

前后端分离 Spring Boot + Vue 开发网易云(附源码)

关注公众号,查看更多优质文章

喜欢就给个“在看

mysql索引失效_导致MySQL索引失效的几种常见写法相关推荐

  1. like左匹配索引失效_导致MySQL索引失效的一些常见写法总结

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

  2. 360 mysql无法启动_安装MySQL 5后无法启动(不能Start service)解决方法小结

    转自:http://www.jb51.net/article/33375.htm 创建primay key过程中发生了断电,当电脑再次启动时候,发现mysql 服务无法启动,使用 net start ...

  3. MySQL学习笔记_关于MySQL的字符类型VARCHAR长度知识总结

    MySQL学习笔记_关于MySQL的字符类型VARCHAR长度知识总结 一.VARCHAR存储和行长度限制 1.VARCHAR(N)中,N指的是字符的长度,VARCHAR类型最大支持65535,指的是 ...

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

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

  5. mysql or走索引吗_加了索引,mysql查询就一定会用吗?

    小白白跑去鹅厂面试,面试官提出了一个很实际的问题: mysql增加索引,那些情况会失效呢?谈一下实际工作中遇到的情况.我们的小白白又抛出了白氏秘籍:用不用索引,找DBA小姐姐!啊?这是你面试哈,还是D ...

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

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

  7. mysql手机客户端_图解MySQL索引--B-Tree(B+Tree)

    看了很多关于索引的博客,讲的大同小异.但是始终没有让我明白关于索引的一些概念,如B-Tree索引,Hash索引,唯一索引....或许有很多人和我一样,没搞清楚概念就开始研究B-Tree,B+Tree等 ...

  8. mysql 离散度_【MySQL】索引原理(四):创建索引的几点建议,列的离散度,前缀索引...

    我们容易有以一个误区,就是在经常使用的查询条件上都建立索引,索引越多越好,那到底是不是这样呢? 因为索引对于改善查询性能的作用是巨大的,所以我们的目标是尽量使用索引.但这并不意味着索引越多越好,因为索 ...

  9. mysql覆盖数据_理解MySQL数据库覆盖索引

    话说有这么一个表: CREATE TABLE`user_group` ( `id`int(11) NOT NULLauto_increment, `uid`int(11) NOT NULL, `gro ...

最新文章

  1. 反激式开关电源中PC817与TL431的配合电路探讨
  2. 30天敏捷结果(19):你在为谁做事?
  3. uaa 授权_使用UAA OAuth2授权服务器–客户端和资源
  4. oracle p l,使用P.A.L制作便携软件 (一) 基本原理 | 么么哒拥有者
  5. 蓝桥杯 算法训练 区间k大数查询
  6. 蒋涛:重新回归的我,将带领 CSDN 全方位升级,为 AI 转型者打造一站式平台
  7. Exchange2007使用POP3/SMTP协议收发邮件
  8. win7旗舰恢复出厂设置_iphone12怎么恢复出厂设置 iphone12还原所有设置方法介绍
  9. MFC开发wps演示
  10. 华为平板android版本如何升级,华为平板怎么升级替换系统 华为平板刷机的教程...
  11. 推荐一款免费的万能电子书格式转换工具电子书转换器NeatConverter
  12. A Pixel-Wise Distance Regression Approach for Joint Retinal Optical Disc and Fovea Detection
  13. xpwifi热点设置android,笔记本xp系统wifi热点设置教程(图文)
  14. Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available
  15. 如何去除 录像开始和结束时 的噔噔噔噔声音
  16. mac电脑开机进入grub界面
  17. 加拿大综合类大学排名获关注,盘点高校对雅思要求
  18. 重头系统的学习,不会咱就学!2014.6.18
  19. 心跳包(确保连接的有效性)
  20. 计算机的两种启动引导方式,硬盘的两种分区和对应启动引导方式

热门文章

  1. Web前端知识技能大汇总
  2. sturst2的原理及环境搭建
  3. 如何adb shell进入ctia模式
  4. 10-10数组的介绍
  5. Java IDE鱼龙混杂,我们该如何选择呢?
  6. 最优化算法python实现篇(3)——无约束一维极值(黄金分割法)
  7. oracle 唯一约束作用,想问下在表上建唯一索引和使用索引+唯一约束,从功能和性能来说有什么差别?...
  8. Boost Asio总结(9)数据缓冲区class mutable_buffer和const_buffer
  9. React如何使用 Ant Design(简单使用)
  10. GetLogicalDrives GetDriveType GetVolumeInformation和FindVolumeClose