|
|
51CTO旗下网站
|
|
移动端

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

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

作者:小强的进阶之路来源:今日头条|2019-12-02 13:36

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

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

  1. CREATE TABLE `employees` ( 
  2.  `id` int(11) NOT NULL AUTO_INCREMENT, 
  3.  `namevarchar(24) NOT NULL DEFAULT '' COMMENT '姓名'
  4.  `age` int(20) NOT NULL DEFAULT '0' COMMENT '年龄'
  5.  `position` varchar(20) NOT NULL DEFAULT '' COMMENT '职位'
  6.  `hire_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '入职时间'
  7.  PRIMARY KEY (`id`), 
  8.  KEY `idx_name_age_position` (`name`,`age`,`position`) USING BTREE 
  9. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='员工表'
  10. insert into employees(name,age,position,hire_time) values('LiLei', 22, 'manager', NOW()) 
  11. insert into employees(name,age,position,hire_time) values('HanMeimei', 23, 'dev', NOW()) 
  12. insert into employees(name,age,position,hire_time) values('Lucy', 23, 'dev', NOW()) 

全值匹配

索引的字段类型是varchar(n):2字节存储字符串长度,如果是utf-8, 则长度是3n+2

  1. EXPLAIN select * from employees where name='LiLei'
工作中遇到的99%SQL优化,这里都能给你解决方案  

  1. EXPLAIN select * from employees where name='LiLei' AND age = 22; 
工作中遇到的99%SQL优化,这里都能给你解决方案

  1. EXPLAIN select * from employees where name='LiLei' AND age = 22 AND position = 'manager'
工作中遇到的99%SQL优化,这里都能给你解决方案  

最左前缀法则

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

  1. EXPLAIN select * from employees where age = 22 AND position='manager'
  2. EXPLAIN select * from employees where position ='manager'
  3. EXPLAIN select * from employees where age=17; 
工作中遇到的99%SQL优化,这里都能给你解决方案  

索引失效

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

  1. EXPLAIN select * from employees where name='LiLei'
工作中遇到的99%SQL优化,这里都能给你解决方案  
  1. EXPLAIN select * from employees where left(name, 3)='LiLei'
工作中遇到的99%SQL优化,这里都能给你解决方案  

给hire_time增加一个普通索引:

  1. alter table `employees` ADD INDEX `idx_hire_time`(`hire_time`) USING BTREE; 
  2. EXPLAIN select * from employees where date(hire_time) = '2019-08-25'
工作中遇到的99%SQL优化,这里都能给你解决方案  

还原最初索引状态

  1. ALTER TABLE `employees` DROP INDEX `idx_hire_time`; 

存储引擎不能使用索引中范围条件右边的列

  1. -- EXPLAIN SELECT * FROM employees WHERE name ='LiLei' AND age=22 AND position ='manager'; 
  2. EXPLAIN SELECT * FROM employees WHERE name ='LiLei' AND age>22 AND position ='manager'
工作中遇到的99%SQL优化,这里都能给你解决方案  

看到key_len这个索引长度是78, 也就是只使用到了前两个字段name和age,postition没有使用到索引的。

覆盖索引

尽量使用覆盖索引(只访问索引的查询(索引列包含查询列)),减少selelct * 语句。

  1. EXPLAIN SELECT name,age,position FROM employees WHERE name ='LiLei' AND age=22 AND position ='manager'
工作中遇到的99%SQL优化,这里都能给你解决方案  

条件判断

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

  1. EXPLAIN SELECT * FROM employees WHERE name !='LiLei' ; 
工作中遇到的99%SQL优化,这里都能给你解决方案  

空值判断

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

  1. EXPLAIN SELECT * FROM employees WHERE name is null
工作中遇到的99%SQL优化,这里都能给你解决方案  

like

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

  1. EXPLAIN SELECT * FROM employees WHERE name LIKE '%Lei'
工作中遇到的99%SQL优化,这里都能给你解决方案  

字符串不加单引号索引失效

  1. EXPLAIN SELECT * FROM employees WHERE name ='1000'
  2. EXPLAIN SELECT * FROM employees WHERE name =1000; 
工作中遇到的99%SQL优化,这里都能给你解决方案  

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

or&in少使用

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

  1. EXPLAIN SELECT * FROM employees WHERE name ='LiLei' or name='HanMeimei'
工作中遇到的99%SQL优化,这里都能给你解决方案  

范围查询优化

给年龄添加单值索引

  1. ALTER TABLE `employees`ADD INDEX `idx_age`(`age`) USING BTREE; 
  2. EXPLAIN select * from employees where age > 1 and age <= 2000; 
工作中遇到的99%SQL优化,这里都能给你解决方案  

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

【编辑推荐】

  1. 详解Oracle数据库的三大索引类型
  2. 10款好用的MySQL GUI工具,数据库管理员的好帮手
  3. 记一次生产环境数据库连接超时自动回收问题及解决方法
  4. 分享一份MySQL一键优化脚本,值得收藏
  5. 一文看懂SQL Server数据库触发器概念、原理及案例
【责任编辑:庞桂玉 TEL:(010)68476606】

点赞 0
分享:
大家都在看
猜你喜欢

订阅专栏+更多

骨干网与数据中心建设案例

骨干网与数据中心建设案例

高级网工必会
共20章 | 捷哥CCIE

403人订阅学习

中间件安全防护攻略

中间件安全防护攻略

4类安全防护
共4章 | hack_man

151人订阅学习

CentOS 8 全新学习术

CentOS 8 全新学习术

CentOS 8 正式发布
共16章 | UbuntuServer

291人订阅学习

读 书 +更多

数据库系统概念

本书是数据库系统方面的经典教材之一。国际上许多著名大学包括斯坦福大学、耶鲁大学、得克萨斯大学、康奈尔大学、伊利诺伊大学、印度理工学...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊

51CTO服务号

51CTO官微