前言

最近一直忙着处理原来老项目遗留的一些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;

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

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

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

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

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

SELECT*FROM`user`WHEREheight=175;

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

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

少年们,切记,切记。

3、函数导致的索引失效

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

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

SELECT*FROM`user`WHEREage-1=20;

5、OR引起的索引失效

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

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

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

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

SELECTs.*FROM`user`sWHERENOTEXISTS(SELECT*FROM`user`uWHEREu.name=s.`name`ANDu.`name`='冰峰')

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

SELECT*FROM`user`WHEREaddressISNULL
SELECT*FROM`user`WHEREaddressISNOTNULL;

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

符合索引

1、最左匹配原则

EXPLAINSELECT*FROM`user`WHEREsex='男';

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

注意:

SELECT*FROM`user`WHEREsex='男'ANDage=22AND`name`='冰峰';
SELECT*FROM`user`WHEREsex='男'AND`name`!='冰峰'ANDage=22;

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

总结

更多相关文章

  1. MySQL 什么时候使用INNER JOIN 或 LEFT JOIN
  2. [android源码下载索引贴】微信+二维码那都不是事......
  3. android中json文件的写法
  4. Android(安卓)UI控件详解-Button(按钮)点击事件的5种写法
  5. android触控,先了解MotionEvent
  6. 系出名门 Android(安卓)系列文章索引
  7. android自定义属性
  8. 系出名门 Android(安卓)系列文章索引
  9. 系出名门 Android(安卓)系列文章索引

随机推荐

  1. XML—XML解析之DOM
  2. XML Http Request最新替代技术—— Fetch
  3. Java&Xml教程(十一)JAXB实现XML与Java对象
  4. php使用simplexml来解析xml
  5. Java对象、Json、Xml转换工具Jackson使用
  6. XML—XML文件约束之DTD详解
  7. 疯狂XML学习笔记(13)---------XML DOM
  8. Java&Xml教程(十)XML作为属性文件使用
  9. XML—XML介绍和基本语法
  10. 疯狂XML学习笔记(12)------------XPath