前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >工作中遇到的99%SQL优化,这里都能给你解决方案

工作中遇到的99%SQL优化,这里都能给你解决方案

作者头像
程序员小强
发布2019-09-03 18:17:49
5250
发布2019-09-03 18:17:49
举报

前几篇文章介绍了mysql的底层数据结构和mysql优化的神器explain。 BAT大厂都会问的MySQL底层数据结构 一线互联网公司必问的MySql优化神器 后台有些朋友说小强只介绍概念,平时使用还是一脸懵,强烈要求小强来一篇实战sql优化,经过周末两天的整理和总结,sql优化实战新鲜出炉, 大家平时学习和工作中,遇到的99% 的sql优化都会介绍到,介于篇幅过长,分成3篇文章哈。

代码语言:javascript
复制
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

代码语言:javascript
复制
EXPLAIN select * from employees where name='LiLei';
代码语言:javascript
复制
EXPLAIN select * from employees where name='LiLei' AND age = 22;
代码语言:javascript
复制
EXPLAIN select * from employees where name='LiLei' AND age = 22 AND position = 'manager';
最左前缀法则

如果索引是多列,要最受最左前缀法则。指的是查询从索引的最左前列开始并且不跳过索引中的列。以下三条sql根据最左前缀法则,都不会走索引。

代码语言:javascript
复制
EXPLAIN select * from employees where age = 22 AND position='manager';
EXPLAIN select * from employees where position ='manager';
EXPLAIN select * from employees where name='LiLei';
索引失效

不要在索引列上做任何操作(计算、函数、类型转换),会导致索引失效而转向全表扫描。

代码语言:javascript
复制
EXPLAIN select * from employees where name='LiLei';
代码语言:javascript
复制
EXPLAIN select * from employees where left(name, 3)='LiLei';

给hire_time增加一个普通索引:

代码语言:javascript
复制
alter table `employees` ADD INDEX `idx_hire_time`(`hire_time`) USING BTREE;
EXPLAIN select * from employees where date(hire_time) = '2019-08-25';

还原最初索引状态

代码语言:javascript
复制
ALTER TABLE `employees` DROP INDEX `idx_hire_time`;
存储引擎不能使用索引中范围条件右边的列
代码语言:javascript
复制
-- 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 * 语句。

代码语言:javascript
复制
EXPLAIN SELECT name,age,position FROM employees WHERE name ='LiLei' AND age=22 AND position ='manager';
条件判断

mysql在使用不等于(! = 或者 <>)的时候无法使用索引会导致全表扫描

代码语言:javascript
复制
EXPLAIN SELECT * FROM employees WHERE name !='LiLei' ;
空值判断

is null,is not null也无法使用索引

代码语言:javascript
复制
EXPLAIN SELECT * FROM employees WHERE name is null;
like

like以通配符开头(‘$abc’)mysql索引失效会变成全表扫描操作

代码语言:javascript
复制
EXPLAIN SELECT * FROM employees WHERE name LIKE '%Lei';
字符串不加单引号索引失效
代码语言:javascript
复制
EXPLAIN SELECT * FROM employees WHERE name ='1000';
EXPLAIN SELECT * FROM employees WHERE name =1000;

不加单引号的字符串,mysql底层会使用cust函数将其转换为字符串,此时索引失效。

or&in少使用

少用or或in,用它查询时,mysql不一定使用索引,mysql内部优化器会根据索引比例、表大小等多个因素整体评估是否使用索引。

代码语言:javascript
复制
EXPLAIN SELECT * FROM employees WHERE name ='LiLei' or name='HanMeimei';
范围查询优化

给年龄添加单值索引

代码语言:javascript
复制
ALTER TABLE `employees`ADD INDEX `idx_age`(`age`) USING BTREE;
EXPLAIN select * from employees where age > 1 and age <= 2000;

没有走索引原因:mysql内部优化器会根据检索比例、表大小等多个因素整体评估是否使用索引。这个例子没有走索引可能是因为单次数据量查询过大导致优化器最终选择不走索引。优化方法:可以将大的范围拆分成多个小范围。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-09-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 MoziInnovations 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 全值匹配
  • 最左前缀法则
  • 索引失效
  • 存储引擎不能使用索引中范围条件右边的列
  • 覆盖索引
  • 条件判断
  • 空值判断
  • like
  • 字符串不加单引号索引失效
  • or&in少使用
  • 范围查询优化
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档