工作中遇到的99%SQL优化,这里都能给你解决方案
前几篇文章介绍了mysql的底层数据结构和mysql优化的神器explain。后台有些朋友说小强只介绍概念,平时使用还是一脸懵,强烈要求小强来一篇实战sql优化,经过周末两天的整理和总结,sql优化实战新鲜出炉, 大家平时学习和工作中,遇到的90% 的sql优化都会介绍到,介意篇幅过长,分成3篇文章哈。
CREATE TABLE `employees` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(24) NOT NULL DEFAULT '' COMMENT '姓名',
`age` int(20) NOT NULL DEFAULT '0' COMMENT '年龄',
`position` varchar(20) NOT NULL DEFAULT '' COMMENT '职位',
`hire_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '入职时间',
PRIMARY KEY (`id`),
KEY `idx_name_age_position` (`name`,`age`,`position`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='员工表';
insert into employees(name,age,position,hire_time) values('LiLei', 22, 'manager', NOW())
insert into employees(name,age,position,hire_time) values('HanMeimei', 23, 'dev', NOW())
insert into employees(name,age,position,hire_time) values('Lucy', 23, 'dev', NOW())
全值匹配
索引的字段类型是varchar(n):2字节存储字符串长度,如果是utf-8, 则长度是3n+2
EXPLAIN select * from employees where name='LiLei';

EXPLAIN select * from employees where name='LiLei' AND age = 22;

EXPLAIN select * from employees where name='LiLei' AND age = 22 AND position = 'manager';

最左前缀法则
如果索引是多列,要最受最左前缀法则。指的是查询从索引的最左前列开始并且不跳过索引中的列。以下两条sql根据最左前缀法则,都不会走索引。
EXPLAIN select * from employees where age = 22 AND position='manager';
EXPLAIN select * from employees where position ='manager';

索引失效
不要在索引列上做任何操作(计算、函数、类型转换),会导致索引失效而转向全表扫描。
EXPLAIN select * from employees where name='LiLei';

EXPLAIN select * from employees where left(name, 3)='LiLei';

给hire_time增加一个普通索引:
alter table `employees` ADD INDEX `idx_hire_time`(`hire_time`) USING BTREE;
EXPLAIN select * from employees where date(hire_time) = '2019-08-25';

还原最初索引状态
ALTER TABLE `employees` DROP INDEX `idx_hire_time`;
存储引擎不能使用索引中范围条件右边的列
-- EXPLAIN SELECT * FROM employees WHERE name ='LiLei' AND age=22 AND position ='manager';
EXPLAIN SELECT * FROM employees WHERE name ='LiLei' AND age>22 AND position ='manager';

看到key_len这个索引长度是78, 也就是只使用到了前两个字段name和age,postition没有使用到索引的。
覆盖索引
尽量使用覆盖索引(只访问索引的查询(索引列包含查询列)),减少selelct * 语句。
EXPLAIN SELECT name,age,position FROM employees WHERE name ='LiLei' AND age=22 AND position ='manager';

条件判断
mysql在使用不等于(! = 或者 <>)的时候无法使用索引会导致全表扫描
EXPLAIN SELECT * FROM employees WHERE name !='LiLei' ;

空值判断
is null,is not null也无法使用索引
EXPLAIN SELECT * FROM employees WHERE name is null;

like
like以通配符开头(‘$abc’)mysql索引失效会变成全表扫描操作
EXPLAIN SELECT * FROM employees WHERE name LIKE '%Lei';

字符串不加单引号索引失效
EXPLAIN SELECT * FROM employees WHERE name ='1000';
EXPLAIN SELECT * FROM employees WHERE name =1000;

不加单引号的字符串,mysql底层会使用cust函数将其转换为字符串,此时索引失效。
or&in少使用
少用or或in,用它查询时,mysql不一定使用索引,mysql内部优化器会根据索引比例、表大小等多个因素整体评估是否使用索引。
EXPLAIN SELECT * FROM employees WHERE name ='LiLei' or name='HanMeimei';

范围查询优化
给年龄添加单值索引
ALTER TABLE `employees`ADD INDEX `idx_age`(`age`) USING BTREE;
EXPLAIN select * from employees where age > 1 and age <= 2000;

没有走索引原因:mysql内部优化器会根据检索比例、表大小等多个因素整体评估是否使用索引。
这个例子没有走索引可能是因为单次数据量查询过大导致优化器最终选择不走索引。
优化方法:可以将大的范围拆分成多个小范围。
还没关注我的公众号?
- 扫文末二维码关注公众号【小强的进阶之路】可领取如下:
- 学习资料: 1T视频教程:涵盖Javaweb前后端教学视频、机器学习/人工智能教学视频、Linux系统教程视频、雅思考试视频教程;
- 100多本书:包含C/C++、Java、Python三门编程语言的经典必看图书、LeetCode题解大全;
- 软件工具:几乎包括你在编程道路上的可能会用到的大部分软件;
- 项目源码:20个JavaWeb项目源码。

工作中遇到的99%SQL优化,这里都能给你解决方案的更多相关文章
- 工作中遇到的99%SQL优化,这里都能给你解决方案(二)
-- 示例表 CREATE TABLE `employees` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(24) NOT NULL ...
- 工作中遇到的99%SQL优化,这里都能给你解决方案(三)
-- 示例表 CREATE TABLE `employees` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(24) NOT NULL ...
- 收集一些工作中常用的经典SQL语句
作为一枚程序员来说和数据库打交道是不可避免的,现收集一下工作中常用的SQL语句,希望能给大家带来一些帮助,当然不全面,欢迎补充! 1.执行插入语句,获取自动生成的递增的ID值 INSERT INTO ...
- 在工作中常用到的SQL
前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 最近在公司做了几张报表,还记得刚开始要做报表的时候都 ...
- 工作中常用到的sql命令!!!
一.mysql数据库日常操作. 1.启动mysql:/etc/init.d/mysql start (前面为mysql的安装路径) 2.重启mysql: /etc/init.d/my ...
- 工作中遇到的一道SQL应用题
登录日志表 CREATE TABLE [dbo].[LoginLog]([Seq] [int] NOT NULL IDENTITY(1, 1), --Seq[UserId] [varchar] (2 ...
- 分享一个工作中遇得到的sql(按每天每人统计拖车次数与小修次数)
查询每人每天的数据 首先先建表 CREATE TABLE `user` ( `name` ) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CR ...
- 《高性能SQL调优精要与案例解析》一书谈SQL调优(SQL TUNING或SQL优化)学习
<高性能SQL调优精要与案例解析>一书上市发售以来,很多热心读者就该书内容及一些具体问题提出了疑问,因读者众多外加本人日常工作的繁忙 ,在这里就SQL调优学习进行讨论并对热点问题统一作答. ...
- Oracle SQl优化总结
对数据库技术的热爱是我唯一的安慰,毕竟这是自己喜欢的事情,还可以做下去. 因为客户项目的需要,我又开始接触Oracle,大部分工作在工作流的优化和业务数据的排查上.为了更好的做这份工作,我有参考过or ...
随机推荐
- docker部署xxl-job 通用反射执行器
原因 最近在公司写一些job,公司使用的是spring boot提供的注解形式实现的. 这样在自测的时候很麻烦,而且测试提测的时候需要修改cron表达式->提交git->jenkins打包 ...
- .NET Core on K8S学习实践系列文章索引(Draft版)
一.关于这个系列 自从去年(2018年)底离开工作了3年的M公司加入X公司之后,开始了ASP.NET Core的实践,包括微服务架构与容器化等等.我们的实践是渐进的,当我们的微服务数量到了一定值时,发 ...
- solr 新建core
D:\tomcat\webapps\solr\solr_home 在该路径下创建一个新的core,所需文件和层级如下 test_core |-- conf |-- schema.xml |-- sol ...
- 调测Onvif事件总结解决办法
主要在调测事件用例的过程中,发现了大量的信息,和未曾碰到的场景和非法错误等信息,先总结解决办法如下: (1)测试过程中发现以前的一个难题解决了,原先在生成soap空间命名的文件中有部分需要下载,离线生 ...
- maven打jar包包括依赖包
<build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId& ...
- 记录eclipse中文出现空格宽度不一致的bug
起因 不久前更新了 eclipse(2019-03) 版本:突然发现出现了,使用注释使用中出现的空格的间隔大小不一致的问题,具体可以看下图: 遇到这种问题简直逼不能忍,在网上搜一下解决方式: 谷歌 搜 ...
- gcd, exgcd的证明
- 一文了解:Redis的RDB持久化
一文了解:Redis的RDB持久化 Redis是内存数据库,为了保证数据不在故障后丢失,Redis需要将数据持久化到硬盘上. Redis持久化有两种方式:一种是快照,全量备份.一种是AOF方式,连续增 ...
- 暴风雨中的 online :.net core 版博客站点遭遇的高并发问题进展
今天暴风雨袭击了杭州,而昨天暴风雨(高并发问题)席卷了园子,留下一片狼藉. 在前天傍晚,我们进行了 .net core 版博客站点的第二次发布尝试,在发布后通过 kestrel 直接监听取代 ngin ...
- 测试自动化:java+selenium3 UI自动化(2) - 启动Firefox
1. selenium和浏览器 基于selenium的这套自动化体系,其实现关键就在于对于各浏览器的顺畅操作. 事实上当selenium刚开始起家的时候,他使用的还是javascript注入的方式来驱 ...