工作中遇到的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项目源码。

原文地址:https://www.cnblogs.com/xiaoqiang-code/p/11455879.html

时间: 2024-11-08 15:55:37

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

收集一些工作中常用的经典SQL语句

作为一枚程序员来说和数据库打交道是不可避免的,现收集一下工作中常用的SQL语句,希望能给大家带来一些帮助,当然不全面,欢迎补充! 1.执行插入语句,获取自动生成的递增的ID值 INSERT INTO SysRole (RoleName,RoleDesc) VALUES('超级管理员','描述') SELECT @@identity as 'id' 2.在同一数据表找到相同属性的记录 SELECT RoleName FROM SysRole GROUP BY RoleName HAVING COU

工作中遇到的Android内存优化问题(1)

最近工作中,遇到了几个内存优化的问题,1.应用退出后,此应用进程保持了不少内存得不到释放,用工具强制gc也无法释放.2.应用进入某些页面瞬间请求分配内存过大.此两个问题对于有经验的开发者很容易猜测一个是内存泄露,一个是图片之类的资源问题.下面来写一个例子分析一下这两个问题 第一个例子是Volley加载图片的app,当此app退出时缓存释放问题 Application类 package demo.memory.com.memorydemo; import android.app.Applicati

数据库优化(十二)-tpch中Q3-Q5仅仅在sql优化方面的分析

--Q3; 1.1执行计划 EXPLAIN EXTENDED SELECT L_ORDERKEY, SUM(L_EXTENDEDPRICE * (1 - L_DISCOUNT)) AS REVENUE, O_ORDERDATE, O_SHIPPRIORITY FROM CUSTOMER, ORDERS, LINEITEM WHERE C_MKTSEGMENT = 'BUILDING' AND C_CUSTKEY = O_CUSTKEY AND L_ORDERKEY = O_ORDERKEY AN

工作中常用到的sql命令!!!

一.mysql数据库日常操作.     1.启动mysql:/etc/init.d/mysql start (前面为mysql的安装路径)     2.重启mysql:  /etc/init.d/mysql restart (前面为mysql的安装路径)     3.关闭mysql:  /etc/init.d/mysql stop(前面为mysql的安装路径)     4.连接本机上的mysql:        mysql -u 用户名 –p (按回车,再输入密码)         例:mysq

工作中遇到的一道SQL应用题

登录日志表 CREATE TABLE [dbo].[LoginLog]([Seq] [int] NOT NULL IDENTITY(1, 1),  --Seq[UserId] [varchar] (20) COLLATE Chinese_PRC_CI_AS NULL, --用户名[LoginTime] [datetime] NULL, --登录时间[SuccessFlg] [bit] NULL, --登录是否成功 ) ON [PRIMARY]GO 需求:返回用户是否能继续登录 登录规则:如果用户

【重磅干货】看了此文,Oracle SQL优化文章不必再看!

听“俊”一席话,胜读十年书.看了这篇由DBA+社群联合发起人丁俊大师(网名:dingjun123)分享的SQL优化大作,其他Oracle SQL优化文章都不必再看了! 专家简介 丁俊 网名:dingjun123 DBA+社群联合发起人 性能优化专家,Oracle ACEA,ITPUB开发版资深版主.8年电信行业从业经验,在某大型电信系统提供商工作7年,任资深工程师,从事过系统开发与维护.业务架构和数据分析.系统优化等工作.擅长基于ORACLE的系统优化,精通SQL.PL/SQL.JAVA等.电子

工程师如何在工作中提升自己?(公众号)

工程师如何在工作中提升自己? 2018-04-21 刘丁 程序人生 点击上方“程序人生”,选择“置顶公众号” 第一时间关注程序猿(媛)身边的故事 引言 古人云:“活到老,学到老.”互联网算是最辛苦的行业之一,“加班”对工程师来说已是“家常便饭”,同时互联网技术又日新月异,很多工程师都疲于应付,叫苦不堪.以至于长期以来流传一个很广的误解:35岁是程序员工作的终点. 如何在繁忙的工作中做好技术积累,构建个人核心竞争力,相信是很多工程师同行都在思考的问题.本文是我自己的一些总结,试图从三个方面来解答:

怎么给工作中重要的pdf文件加密

怎么给工作中重要的pdf文件加密?大家在工作中都会接触一些合作项目的重要文件.这些重要文件有时候就会影响整个合作项目的成功与否.因此大家对于这些重要文件的保护意识都非常强.因为pdf文件属于安全性较高的文件格式,所以大家就会将重要的工作文件以pdf格式保存.并且为了防患于未然,还会给pdf文件进行加密.在接下来得文章内容里,就会告诉大家如何给工作中的pdf文件添加密码. 1.搜索关键词pdf在线加密.大家打开自己电脑中的百度浏览器,然后在其中查找关键词pdf在线加密,接着点击进入搜索到得相关页面

Sql优化器究竟帮你做了哪些工作?

关系型数据库的一大优势之一,用户无需关心数据的访问方式,因为这些优化器都帮我们处理好了,但sql查询优化的时候,我不得不要对此进行关注,因为这牵扯到查询性能问题. 有经验的程序员都会对一些sql优化了如指掌,比如我们常说的最左匹配原则,非BT谓词规避等等,那么优化器是如何确定这些的?以及为何一定要最左匹配,最左匹配的原理是什么,你是否有深入了解? 这一篇我们就通过一些实例来剖析优化器做了哪些工作,以方便我们更好的优化SQL查询. 本篇你可以知道: sql的访问路径是什么 优化器如何确定最优访问路