MySQL常见优化方案汇总
作者:一点光辉 发布时间:2024-01-23 05:29:35
mysql优化是我们日常工作经常遇到的问题,今天给大家说下MySQL常见的几种优化方案。
注:原始资料来自享学课堂,自己加上整理和思考
思考sql优化的几个地方,我把他做了个分类,方便理解
select [字段 优化1]:主要是覆盖索引
from []
where [条件 优化2]
union [联合查询 优化3]
新建表格
CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(50) DEFAULT NULL COMMENT '姓名',
`age` int(11) DEFAULT NULL COMMENT '年龄',
`phone` varchar(12) DEFAULT NULL,
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
添加索引,添加索引之后
key_len:根据这个值,就可以判断索引使用情况,特别是在组合索引的时候,判断所有的索引字段是否都被查询用到。
key_len计算方式简单介绍
latin1占用1个字节,gbk占用2个字节,utf8占用3个字节
不允许为空:
varchar(10):10*3
char(10):10*3+2
int:4
允许为空:
varchar(10):10*3+1
char(10):10*3+2+1
int:4+1
使用完全索引key_len=name(50*3+2+1=153)+age(4+1)+phone(12*3+2+1=39)
alter table studen add index name_age_phone(name, age, phone);
添加数据
insert into student(name,age,phone,create_time) values('赛文',1000,'15717177664',now());
insert into student(name,age,phone,create_time) values('雷欧',1200,'15733337664',now());
insert into student(name,age,phone,create_time) values('泰罗',800,'15714447664',now());
一、优化点1:字段优化
覆盖索引尽量用
简单解释解释,索引是哪几个列,就查询哪几个列: 覆盖索引的原因:索引是高效找到行的一个方法,但是一般数据库也能使用 索引找到一个列的数据,因此它 不必读取整个行。毕竟索引叶子节点存储了它们索引的数据; 当能通过读取索引就可以得到想要的数据,那就不需要读取行了。一个索引 包含了(或 覆盖了)满足查询结果的数据就叫做覆盖索引 注意:有索引尽量不要使用select *
#未覆盖索引
EXPLAIN SELECT * FROM student WHERE NAME = '泰罗' and age =1000 and phone='15717177664';
#覆盖了索引
EXPLAIN SELECT name,age,phone FROM student WHERE NAME = '泰罗' and age =1000 and phone='15717177664';
#包含了索引
EXPLAIN SELECT name FROM student WHERE NAME = '泰罗' and age =1000 and phone='15717177664';
#加上主键也还是覆盖索引
EXPLAIN SELECT id, name,age,phone FROM student WHERE NAME = '泰罗' and age =1000 and phone='15717177664';
未使用覆盖索引
使用完全覆盖索引
使用包含覆盖索引
加上主键还是覆盖索引
二、优化点2:where优化
1.尽量全值匹配
EXPLAIN SELECT * FROM student WHERE NAME = '赛文';
EXPLAIN SELECT * FROM student WHERE NAME = '雷欧' AND age = 1200;
EXPLAIN SELECT * FROM student WHERE NAME = '泰罗' AND age = 800 AND phone = '15714447664';
执行结果,三个都用到了索引,但是key_len是不同的,key_len=197,表示所有索引都使用到了
当建立了索引列后,能在 wherel 条件中使用索引的尽量所用。
2.最佳左前缀法则
最左前缀法则:指的是查询从索引的最左前列开始并且不跳过索引中的列。 我们定义的索引顺序是 name_age_phone ,所以查询的时候也应该从name开始,然后age,然后phone 情况1:从age、phone开始查询,tpye=All,key = null,没使用索引
情况2:从phone开始查询,type=All,key=null,未使用索引
情况3:从name开始,type=ref,使用了索引
3.范围条件放最后
没有使用范围查询,key_len=197,使用到了name+age+phone组合索引
EXPLAIN SELECT * FROM student WHERE NAME = '泰罗' AND age = 1000 AND phone = '15717177664';
使用了范围查询,key_len从197变为158,即除了name和age,phone索引失效了
EXPLAIN SELECT * FROM student WHERE NAME = '泰罗' AND age > 800 AND phone = '15717177664';
key_len=name(153)+age(5)
4.不在索引列上做任何操作
EXPLAIN SELECT * FROM student WHERE NAME = '泰罗';
EXPLAIN SELECT * FROM student WHERE left(NAME,1) = '泰罗';
不做计算,key_len有值,key_len=153,有使用name索引
做了截取结算,type=All,key_len=null,未使用索引
5.不等于要甚用
mysql 在使用不等于 (!= 或者 <>) 的时候无法使用索引会导致全表扫描
#有使用到索引
EXPLAIN SELECT * FROM student WHERE NAME = '泰罗';
#不等于查询,未使用到索引
EXPLAIN SELECT * FROM student WHERE NAME != '泰罗';
EXPLAIN SELECT * FROM student WHERE NAME <> '泰罗';
#如果定要需要使用不等于,请用覆盖索引
EXPLAIN SELECT name,age,phone FROM student WHERE NAME != '泰罗';
EXPLAIN SELECT name,age,phone FROM student WHERE NAME <> '泰罗';
使用不等于查询,跳过索引
使用不等于查询,同时使用覆盖索引,此时可以使用到索引
6.Null/Not null有影响
修改为非空
那么为not null,此时导致索引失效
EXPLAIN select * from student where name is null;
EXPLAIN select * from student where name is not null;
改为可以为空
查询为空,索引起作用了
查询非空索引失效
解决方法:
使用覆盖索引(覆盖索引解千愁)
7、Like 查询要当心 like
以通配符开头 ('%abc...')mysql 索引失效会变成全表扫描的操作
#like 以通配符开头('%abc...')mysql 索引失效会变成全表扫描的操作
#索引有效
EXPLAIN select * from student where name ='泰罗';
#索引失效
EXPLAIN select * from student where name like '%泰罗%';
#索引失效
EXPLAIN select * from student where name like '%泰罗';
#索引有效
EXPLAIN select * from student where name like '泰罗%';
解决方式:覆盖索引
EXPLAIN select name,age,phone from student where name like '%泰罗%';
使用覆盖索引能够解决
8.字符类型加引号
字符串不加单引号索引失效(这个看着有点鸡肋了,一般查询字符串都会加上引号)
使用覆盖索引解决
三、优化3
1.OR 改 UNION 效率高
未使用索引
EXPLAIN select * from student where name='泰罗' or name = '雷欧';
使用索引
EXPLAIN
select * from student where name='泰罗'
UNION
select * from student where name = '雷欧';
解决方式:覆盖索引
EXPLAIN select name,age from student where name='泰罗' or name = '雷欧';
使用or未使用到索引
使用union,使用了索引
解决方式:覆盖索引
来源:https://blog.csdn.net/qq_22701869/article/details/119651504
猜你喜欢
- 英文文档:staticmethod(function)Return a static method for function.A stati
- 这篇文章主要介绍了如何基于Python获取图片的物理尺寸,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的
- 安装环境:python版本2.7.5 ,win7系统安装Djangohttps://www.djangoproject.com/downlo
- 求:机房、线上有多台主机,为了保障安全,需要定期修改密码。若手动修改,费时费力易出错。程序应该满足如下需求 :1、在现有的excel密码表格
- 昨天装了个SQL2000,打开企业管理器,发现SQL Server组下面没有任何的内容,提示“无项目”。之前sa设置的都是空密码就没碰到这个
- 这是一个网页设计中经常会用到的图片特效,实现多个图片之间的轮换,并分别带有连接。以前的代码只能适用于IE,在FF下始终没有得到很好的解决今天
- 自己的小Python项目好几天没有写了,今天打开PyCharm准备继续写,突然发现之前的激活码被取消不能用了,本来激情满满的准备干活啦!之前
- 示例: 创建Table CREATE TABLE [dbo].[xmlTable]( [id] [int] IDENTITY(1,1) NO
- numpy array存储为.npy存储:import numpy as npnumpy_array = np.array([1,2,3])
- Vue实践分享(三)在实际项目的开发过程中,经常会遇到页面还没渲染完成而插件就已经开始加载的问题,这样就会导致显示和功能出错。可以通过Vue
- 前言最近空闲的时候看到了之前就关注的一个小站http://teahour.fm/,一直想把这里的音频都听一遍,可转眼间怎么着也有两年了,却什
- 环境springboot、mybatisPlus、mysql8mysql8(部署在1核2G的服务器上,很卡,所以下面的数据条数用5000,太
- ORACLE的数据字典是数据库的重要组成部分之一,它随着数据库的产生而产生, 随着数据库的变化而变化, 体现为sys用户下的一些表和视图。数
- 万维网联盟(W3C)发布了HTML 5规格说明书的草稿 ,这是自HTML 4在十多年前发布以来的第一个主要的修订版.在这期间,随着开发者逐渐
- pytest fixtures装饰器pytest中可以使用@pytest.fixture 装饰器来装饰一个方法,被装饰方法的方法名可以作为一
- 简介这个模块处理python中常见类型数据和Python bytes之间转换。这可用于处理存储在文件或网络连接中的bytes数据以及其他来源
- Python有自己内置的标准GUI库--Tkinter,只要安装好Python就可以调用。今天学习到了图形界面设计的问题,刚开始就卡住了。为
- Python的3.0版本,常被称为Python 3000,或简称Py3k。相对于Python的早期版本,这是一个较大的升级。为了不带入过多的
- 代码如下:<% FunctIon DownloadFIle(StrFIle) StrFIlename=StrFIle Response
- 本节讲解了 flask 的请求,如果想在没有请求的情况下获取上下文,可以使用test_request_context()或者request_