mysql索引失效_导致MySQL索引失效的几种常见写法
最近一直忙着处理原来老项目遗留的一些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索引失效的几种常见写法相关推荐
- like左匹配索引失效_导致MySQL索引失效的一些常见写法总结
前言 最近一直忙着处理原来老项目遗留的一些SQL优化问题,由于当初表的设计以及字段设计的问题,随着业务的增长,出现了大量的慢SQL,导致MySQL的CPU资源飙升,基于此,给大家简单分享下这些比较使用 ...
- 360 mysql无法启动_安装MySQL 5后无法启动(不能Start service)解决方法小结
转自:http://www.jb51.net/article/33375.htm 创建primay key过程中发生了断电,当电脑再次启动时候,发现mysql 服务无法启动,使用 net start ...
- MySQL学习笔记_关于MySQL的字符类型VARCHAR长度知识总结
MySQL学习笔记_关于MySQL的字符类型VARCHAR长度知识总结 一.VARCHAR存储和行长度限制 1.VARCHAR(N)中,N指的是字符的长度,VARCHAR类型最大支持65535,指的是 ...
- mysql group 索引失效_介绍mysql索引失效的情况
mysql视频教程栏目索引失效的情况. 索引对于MySQL而言,是非常重要的篇章.索引知识点也巨多,要想掌握透彻,需要逐个知识点一一击破,今天来先来聊聊哪些情况下会导致索引失效. 图片总结版 相关免费 ...
- mysql or走索引吗_加了索引,mysql查询就一定会用吗?
小白白跑去鹅厂面试,面试官提出了一个很实际的问题: mysql增加索引,那些情况会失效呢?谈一下实际工作中遇到的情况.我们的小白白又抛出了白氏秘籍:用不用索引,找DBA小姐姐!啊?这是你面试哈,还是D ...
- mysql的覆盖索引原理_「Mysql索引原理(七)」覆盖索引
通常大家都会根据查询的WHERE条件来创建合适的索引,不过这只是索引优化的一个方面.设计优秀的索引应该考虑到整个查询,而不单单是WHERE条件部分.索引确实是一种查找数据的高效方式,但是MySQL也可 ...
- mysql手机客户端_图解MySQL索引--B-Tree(B+Tree)
看了很多关于索引的博客,讲的大同小异.但是始终没有让我明白关于索引的一些概念,如B-Tree索引,Hash索引,唯一索引....或许有很多人和我一样,没搞清楚概念就开始研究B-Tree,B+Tree等 ...
- mysql 离散度_【MySQL】索引原理(四):创建索引的几点建议,列的离散度,前缀索引...
我们容易有以一个误区,就是在经常使用的查询条件上都建立索引,索引越多越好,那到底是不是这样呢? 因为索引对于改善查询性能的作用是巨大的,所以我们的目标是尽量使用索引.但这并不意味着索引越多越好,因为索 ...
- mysql覆盖数据_理解MySQL数据库覆盖索引
话说有这么一个表: CREATE TABLE`user_group` ( `id`int(11) NOT NULLauto_increment, `uid`int(11) NOT NULL, `gro ...
最新文章
- 反激式开关电源中PC817与TL431的配合电路探讨
- 30天敏捷结果(19):你在为谁做事?
- uaa 授权_使用UAA OAuth2授权服务器–客户端和资源
- oracle p l,使用P.A.L制作便携软件 (一) 基本原理 | 么么哒拥有者
- 蓝桥杯 算法训练 区间k大数查询
- 蒋涛:重新回归的我,将带领 CSDN 全方位升级,为 AI 转型者打造一站式平台
- Exchange2007使用POP3/SMTP协议收发邮件
- win7旗舰恢复出厂设置_iphone12怎么恢复出厂设置 iphone12还原所有设置方法介绍
- MFC开发wps演示
- 华为平板android版本如何升级,华为平板怎么升级替换系统 华为平板刷机的教程...
- 推荐一款免费的万能电子书格式转换工具电子书转换器NeatConverter
- A Pixel-Wise Distance Regression Approach for Joint Retinal Optical Disc and Fovea Detection
- xpwifi热点设置android,笔记本xp系统wifi热点设置教程(图文)
- Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available
- 如何去除 录像开始和结束时 的噔噔噔噔声音
- mac电脑开机进入grub界面
- 加拿大综合类大学排名获关注,盘点高校对雅思要求
- 重头系统的学习,不会咱就学!2014.6.18
- 心跳包(确保连接的有效性)
- 计算机的两种启动引导方式,硬盘的两种分区和对应启动引导方式
热门文章
- Web前端知识技能大汇总
- sturst2的原理及环境搭建
- 如何adb shell进入ctia模式
- 10-10数组的介绍
- Java IDE鱼龙混杂,我们该如何选择呢?
- 最优化算法python实现篇(3)——无约束一维极值(黄金分割法)
- oracle 唯一约束作用,想问下在表上建唯一索引和使用索引+唯一约束,从功能和性能来说有什么差别?...
- Boost Asio总结(9)数据缓冲区class mutable_buffer和const_buffer
- React如何使用 Ant Design(简单使用)
- GetLogicalDrives GetDriveType GetVolumeInformation和FindVolumeClose