MySQL常见优化方案汇总

目录
  • 思考sql优化的几个地方,我把他做了个分类,方便理解
    • key_len计算方式简单介绍
  • 一、优化点1:字段优化
    • 覆盖索引尽量用
  • 二、优化点2:where优化
    • 1.尽量全值匹配
    • 2.最佳左前缀法则
    • 3.范围条件放最后
    • 4.不在索引列上做任何操作
    • 5.不等于要甚用
    • 6.Null/Not null有影响
    • 7、Like 查询要当心 like
    • 8.字符类型加引号
  • 三、优化3
    • 1.OR 改 UNION 效率高

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,使用了索引

解决方式:覆盖索引

到此这篇关于MySQL常见优化方案汇总的文章就介绍到这了,更多相关MySQL优化方案内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • MySQL limit分页大偏移量慢的原因及优化方案

    在 MySQL 中通常我们使用 limit 来完成页面上的分页功能,但是当数据量达到一个很大的值之后,越往后翻页,接口的响应速度就越慢. 本文主要讨论 limit 分页大偏移量慢的原因及优化方案,为了模拟这种情况,下面首先介绍表结构和执行的 SQL. 场景模拟 建表语句 user 表的结构比较简单,id.sex 和 name,为了让 SQL 的执行时间变化更加明显,这里有9个姓名列. CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREME

  • 浅谈MySQL大表优化方案

    背景 阿里云RDS FOR MySQL(MySQL5.7版本)数据库业务表每月新增数据量超过千万,随着数据量持续增加,我们业务出现大表慢查询,在业务高峰期主业务表的慢查询需要几十秒严重影响业务 方案概述 一.数据库设计及索引优化 MySQL数据库本身高度灵活,造成性能不足,严重依赖开发人员的表设计能力以及索引优化能力,在这里给几点优化建议 时间类型转化为时间戳格式,用int类型储存,建索引增加查询效率 建议字段定义not null,null值很难查询优化且占用额外的索引空间 使用TINYINT类

  • mysql查询优化之100万条数据的一张表优化方案

    1.两种查询引擎查询速度(myIsam 引擎 ) InnoDB 中不保存表的具体行数,也就是说,执行select count(*) from table时,InnoDB要扫描一遍整个表来计算有多少行. MyISAM只要简单的读出保存好的行数即可. 注意的是,当count(*)语句包含 where条件时,两种表的操作有些不同,InnoDB类型的表用count(*)或者count(主键),加上where col 条件.其中col列是表的主键之外的其他具有唯一约束索引的列.这样查询时速度会很快.就是可

  • MySQL优化方案参考

    优化可能带来的问题 优化不总是对一个单纯的环境进行,还很可能是一个复杂的已投产的系统. 优化手段本来就有很大的风险,只不过你没能力意识到和预见到! 任何的技术可以解决一个问题,但必然存在带来一个问题的风险! 对于优化来说解决问题而带来的问题,控制在可接受的范围内才是有成果. 保持现状或出现更差的情况都是失败! 本文整理了一些MySQL的通用优化方法,做个简单的总结分享,旨在帮助那些没有专职MySQL DBA的企业做好基本的优化工作,至于具体的SQL优化,大部分通过加适当的索引即可达到效果,更复杂

  • MySQL 函数索引的优化方案

    很多开发人员在使用MySQL时经常会在部分列上进行函数计算等,导致无法走索引,在数据量大的时候,查询效率低下.针对此种情况本文从MySQL5.7 及MySQL8.0中分别进行不同方式的优化. 1. MySQL5.7 MySQL5.7版本中不支持函数索引,因此 遇到函数索引的时候需要进行修改,否则即使查询的字段上有索引,执行时也无法使用索引而进行全表扫描,数据量大的表查询时间会比较长.具体案例如下: 1.1 创建测试表及数据 mysql> use testdb; Database changed

  • 浅谈MySQL之select优化方案

    目录 生活中的例子 慢查询 如何去优化 count limit 最大值最小值min&max 生活中的例子 我们是否看到过在公司中许多查询语句都是select * xxxx 心中的想法肯定是,别人写了select *,那我写吧,省去了不少麻烦事儿 慢查询 首先去思考,最基本的,是否我们使用的数据库插查询语句存在了访问的数据太多 其实大部分性能低的查询往往都可以通过减少访问的数据量来优化的 因为select * 会给服务器带来额外的I/O.内存和cpu的消耗 数据库中慢查询开销的三个指标 相应时间

  • MySQL优化方案之开启慢查询日志

    目录 前言 设置慢查询日志 测试 附:日志分析工具mysqldumpslow 总结 前言 本方案只适应于小的项目.项目未上线或者紧急情况下可采用这种方式,一旦开启慢日志查询会增加数据库的压力,所以一般采用后台对数据操作时间写入日志文件中,每一周定时进行清除日志 mysql优化方案:开启慢查询日志(查询sql执行超过一秒以上sql等等) 开启慢查询日志:可以让MySQL记录下查询超过指定时间的语句,通过定位分析性能的瓶颈,才能更好的优化数据库系统的性能. 参数说明: slow_query_log

  • MySQL常见优化方案汇总

    目录 思考sql优化的几个地方,我把他做了个分类,方便理解 key_len计算方式简单介绍 一.优化点1:字段优化 覆盖索引尽量用 二.优化点2:where优化 1.尽量全值匹配 2.最佳左前缀法则 3.范围条件放最后 4.不在索引列上做任何操作 5.不等于要甚用 6.Null/Not null有影响 7.Like 查询要当心 like 8.字符类型加引号 三.优化3 1.OR 改 UNION 效率高 mysql优化是我们日常工作经常遇到的问题,今天给大家说下MySQL常见的几种优化方案. 注:

  • Mysql性能优化方案分享

    网上有不少mysql 性能优化方案,不过,mysql的优化同sql server相比,更为麻烦,同样的设置,在不同的环境下 ,由于内存,访问量,读写频率,数据差异等等情况,可能会出现不同的结果,因此简单地根据某个给出方案来配置mysql是行不通的,最好能使用status信息对mysql进行具体的优化. mysql> show global status; 可以列出MySQL服务器运行各种状态值,另外,查询MySQL服务器配置信息语句: mysql> show variables; 一.慢查询

  • 详解Java代码常见优化方案

    首先,良好的编码规范非常重要.在 java 程序中,访问速度.资源紧张等问题的大部分原因,都是代码不规范造成的. 单例的使用场景 单例模式对于减少资源占用.提高访问速度等方面有很多好处,但并不是所有场景都适用于单例. 简单来说,单例主要适用于以下三个方面: 多线程场景,通过线程同步来控制资源的并发访问. 多线程场景,控制数据共享,让多个不相关的进程或线程之间实现通信(通过访问同一资源来控制). 控制实例的产生,单例只实例化一次,以达到节约资源的目的: 不可随意使用静态变量 当某个对象被定义为 s

  • MySQL常用分库分表方案汇总

    目录 一.数据库瓶颈 二.分库分表 2.水平分表 3.垂直分库 4.垂直分表 三.分库分表工具 四.分库分表步骤 五.分库分表问题 1.非partition key的查询问题 2.非partition key跨库跨表分页查询问题 3.扩容问题 六.分库分表总结 一.数据库瓶颈 不管是IO瓶颈,还是CPU瓶颈,最终都会导致数据库的活跃连接数增加,进而逼近甚至达到数据库可承载活跃连接数的阈值.在业务Service来看就是,可用数据库连接少甚至无连接可用.接下来就可以想象了吧(并发量.吞吐量.崩溃).

  • MySQL select count(*)计数很慢优化方案

    目录 前言 1. MyISAM存储引擎计数为什么这么快? 2. 能不能手动实现统计总行数 3. InnoDB引擎能否实现快速计数 4. 四种计数方式的性能差别 前言 在日常开发工作中,我经常会遇到需要统计总数的场景,比如:统计订单总数.统计用户总数等.一般我们会使用MySQL 的count函数进行统计,但是随着数据量逐渐增大,统计耗时也越来越长,最后竟然出现慢查询的情况,这究竟是什么原因呢?本篇文章带你一下学习一下. 1. MyISAM存储引擎计数为什么这么快? 我们总有个错觉,就是感觉MyIS

  • mysql 查询重复的数据的SQL优化方案

    在mysql中查询不区分大小写重复的数据,往往会用到子查询,并在子查询中使用upper函数来将条件转化为大写.如: 复制代码 代码如下: select * from staticcatalogue WHERE UPPER(Source) IN (SELECT UPPER(Source) FROM staticcatalogue GROUP BY UPPER(Source) having count(UPPER(Source))>1) ORDER BY upper(Source) DESC; 这条

  • MySQL服务器 IO 100%的分析与优化方案

    前言 压力测试过程中,如果因为资源使用瓶颈等问题引发最直接性能问题是业务交易响应时间偏大,TPS逐渐降低等.而问题定位分析通常情况下,最优先排查的是监控服务器资源利用率,例如先用TOP 或者nmon等查看CPU.内存使用情况,然后在排查IO问题,例如网络IO.磁盘IO的问题. 如果是磁盘IO问题,一般问题是SQL语法问题.MYSQL参数配置问题.服务器自身硬件瓶颈导致IOPS吞吐率问题. 本文主要给大家介绍的是关于MySQL服务器 IO 100%的分析与优化方案,下面话不多说了,来一起看看详细的

随机推荐