MySQL数据库是常见的两个瓶颈是CPU和I/O的瓶颈,CPU在饱和的时候一般发生在大量数据进行比对或聚合时。磁盘I/O瓶颈发生在装入数据远大于内存容量的时候,如果应用分布在网络上,那么查询量相当大的时候那么平瓶颈就会出现在网络上。而出现上诉情况最常见的就是慢查询导致。本文就将对慢查询优化进行简单介绍,一是介绍慢查询的分析语句EXPLAIN,一是通过部分常见的慢查询进行分析讲解,希望读完后能对查询优化有所提高。

EXPLAIN命令用于SQL语句的查询执行计划(QEP)。这条命令的输出结果能够让我们了解MySQL 优化器是如何执行SQL 语句的。这条命令并没有提供任何调整建议,但它能够提供重要的信息帮助我们做出优化决策。

EXPLAIN结果集为id,select_type,table,type,possible_keys,key,key_len

,ref,rows,Extra,本文主要针对select_type,type,ref,Extra进行讲解。

select_type 列提供了各种表示table 列引用的使用方式的类型。最常见的值包括SIMPLE、PRIMARY、DERIVED 和UNION。其他可能的值还有UNION RESULT、DEPENDENT SUBQUERY、DEPENDENT UNION、UNCACHEABLE UNION 以及UNCACHEABLE QUERY。

  1. SIMPLE:对于不包含子查询和其他复杂语法的简单查询,这是一个常见的类型。(这个也是最理想的)
  2. PRIMARY:这是为更复杂的查询而创建的首要表(也就是最外层的表)。这个类型通常可以在DERIVED 和UNION 类型混合使用时见到。
  3. DERIVED:当一个表不是一个物理表时,那么就被叫做DERIVED。一般代表生成了临时表或子查询,建议优化。
  4. UNION:这是UNION 语句其中的一个SQL 元素。代表使用了UNION,建议优化

type这是最重要的字段之一,显示查询使用了何种类型。从最好到最差的连接类型为system、const、eq_reg、ref、range、index和ALL:

  1. system、const:可以将查询的变量转为常量.  如id=1; id为 主键或唯一键.
  2. eq_ref:访问索引,返回某单一行的数据.(通常在联接时出现,查询使用的索引为主键或惟一键)
  3. ref:访问索引,返回某个值的数据.(可以返回多行) 通常使用=时发生
  4. range:这个连接类型使用索引返回一个范围中的行,比如使用>或<查找东西,并且该字段上建有索引时发生的情况(注:不一定好于index)
  5. index:以索引的顺序进行全表扫描,优点是不用排序,缺点是还要全表扫描
  6. ALL:全表扫描,应该尽量避免

前面简单介绍了EXPLAIN的结果集,下面将通过生产实际的慢查询来进行优化讲解。

案例1:

执行顺序通过ID判断,从大到小,首先从select_type为DERIVED,type为index,Extra为NULL可得出该查询对yyd_advert_activation_record进行了全表查询,然后从select_type为PRIMARY,table为<derived2>,type为all,Extra为Using temporary; Using filesort可得出查询使用子查询,生成了临时表并排序。

出现这种语句,首先线上不应该有这种全量统计类的需求,而且并发较高,这个对线上会造成极大的压力。其次该语句的语法上没有优化空间,从数据上看,这个张表从17年1月就没有数据更新,这个查询每次查询数据一致,所以这个查询需求联系开发删除。

案例2:

该查询select_type为SIMPLE,possible_key为index_user_id可以看出user_id上有索引,但是type为all,Extra为Using where可以看出这个查询实际是全表扫描USER_ID LIKE '23930525',仔细分析USER_ID的数据类型为BIGINT(20),就可知该查询问题在于使用了like,使得USER_ID转换为varchar类型进行匹配,导致索引无法使用。该查询优化建议为将like改为=

案例3:

从结果集可以看出这个查询使用了两次子查询,并且在第二个子查询中使用了临时表排序,虽然rows显示查询量不大,但实际查询还是全表扫描。该查询实际执行需要14秒,扫描17W+数据。

仔细分析该查询,两个子查询关联条件和表都一致,第二个子查询只是进行了group by和distinct排序和聚合,但是结果fushu_id又是表的关联条件,所以第二个子查询完全没有必要,直接修改为如下即可。查询优化后只需0.004s。

案例4:

虎哥:
我们这边要在对账库上进行insert select, 但是发现这条语句效率极低,已经执行2小时以上,根本不出结果
INSERT into mt_M_direct_1807_A11 SELECT * from mt_M_direct_1807_A1 a GROUP BY a.`订单id` HAVING COUNT(a.`订单id`) >1; 很慢, 将这条语句拆解成
请DBA帮忙查一下原因

我:

SELECT a.* from mt_M_direct_1807_A1 a GROUP BY a.`订单id` HAVING COUNT(a.`订单id`) >1; 这个也很慢,但是执行
SELECT a.`订单id` from mt_M_direct_1807_A1 a GROUP BY a.`订单id` HAVING COUNT(a.`订单id`) >1 这个就很快,
优化后,insert执行,只需要20S的时间,可以将语句优化成:
insert into mt_M_direct_1807_A11 SELECT b.* from mt_M_direct_1807_A1 b where b.`订单id` FROM (SELECT a.`订单id` from mt_M_direct_1807_A1 a GROUP BY a.`订单id` HAVING COUNT(a.`订单id`) >1);

以上只是比较典型的慢查询优化案例,线上还有很多类型的情况导致慢查询的产生从而影响服务器性能和程序效率,希望今后在开发SQL的时候能够多考虑相关情况,可通过EXPLAIN来进行判断是否查询性能有问题,编写优质代码。

MySQL慢查询优化的更多相关文章

  1. php mysql 一个查询优化的简单例子

    PHP+Mysql是一个最经常使用的黄金搭档,它们俩配合使用,能够发挥出最佳性能,当然,如果配合Apache使用,就更加Perfect了. 因此,需要做好对mysql的查询优化.下面通过一个简单的例子 ...

  2. WebAPI调用笔记 ASP.NET CORE 学习之自定义异常处理 MySQL数据库查询优化建议 .NET操作XML文件之泛型集合的序列化与反序列化 Asp.Net Core 轻松学-多线程之Task快速上手 Asp.Net Core 轻松学-多线程之Task(补充)

    WebAPI调用笔记   前言 即时通信项目中初次调用OA接口遇到了一些问题,因为本人从业后几乎一直做CS端项目,一个简单的WebAPI调用居然浪费了不少时间,特此记录. 接口描述 首先说明一下,基于 ...

  3. MySQL in查询优化

    https://blog.csdn.net/gua___gua/article/details/47401621 MySQL in查询优化<一> 原创 2015年08月10日 17:57: ...

  4. 查询优化 | MySQL慢查询优化

    ​Explain查询:rows,定位性能瓶颈. 只需要一行数据时,使用LIMIT1. 在搜索字段上建立索引. 使用ENUM而非VARCHAR. 选择区分度高的列作为索引. 采用扩展索引,而不是新建索引 ...

  5. MySQL 慢查询优化

    为什么查询速度会慢 1.慢是指一个查询的响应时间长.一个查询的过程: 客户端发送一条查询给服务器 服务器端先检查查询缓存,如果命中了缓存,则立可返回存储在缓存中的结果.否则进入下一个阶段 服务器端进行 ...

  6. MySQL SQL查询优化技巧详解

    MySQL SQL查询优化技巧详解 本文总结了30个mysql千万级大数据SQL查询优化技巧,特别适合大数据里的MYSQL使用. 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 ...

  7. 关于mysql的查询优化

    由于工作原因,最近甲方客户那边多次反应了他们那边的系统查询速度慢,经过排除之后,发现他们那边的数据库完全没有用到索引,简直坑得一笔,通过慢查询日志分析,为数据表建立了适当的索引之后,查询速度明显的提高 ...

  8. 《MySQL慢查询优化》之SQL语句及索引优化

    1.慢查询优化方式 服务器硬件升级优化 Mysql服务器软件优化 数据库表结构优化 SQL语句及索引优化 本文重点关注于SQL语句及索引优化,关于其他优化方式以及索引原理等,请关注本人<MySQ ...

  9. MySQL 的查询优化

    说起 MySQL 的查询优化,相信大家收藏了一堆奇技淫巧:不能使用 SELECT *.不使用 NULL 字段.合理创建索引.为字段选择合适的数据类型..... 你是否真的理解这些优化技巧?是否理解它背 ...

随机推荐

  1. bzoj千题计划142:bzoj3144: [Hnoi2013]切糕

    http://www.lydsy.com/JudgeOnline/problem.php?id=3144 如果D=2 ,两个点,高度为4,建图如下 #include<queue> #inc ...

  2. seaborn基础整理

    seaborn是基于matplotlib的更高级的做图工具,下面主要针对以下几个部分进行整理: 第一部分:https://douzujun.github.io/page/%E6%95%B0%E6%8D ...

  3. lvm--pv丢失后恢复

    [root@db-backup ~]# vgcfgrestore vg_backup  Couldn't find device with uuid JgYDQu-R1AG-wrD2-AHpX-A14 ...

  4. 【leetcode 简单】 第九十五题 数字转换为十六进制数

    给定一个整数,编写一个算法将这个数转换为十六进制数.对于负整数,我们通常使用 补码运算 方法. 注意: 十六进制中所有字母(a-f)都必须是小写. 十六进制字符串中不能包含多余的前导零.如果要转化的数 ...

  5. transform动画效果

     transform动画效果 transform :移动,旋转.倾斜.缩放.     transform:translate(0,300px); x代表的是水平的偏移距离,y代表垂直的.      t ...

  6. 自动检测SOCKET链接断开

    如何判断SOCKET已经断开 最近在做一个服务器端程序,C/S结构.功能方面比较简单就是client端与server端建立连接,然后发送消息给server.我在server端会使用专门的线程处理一条s ...

  7. PyText

    Facebook开源了自家工程师们一直在用的NLP建模框架PyText.这个框架,每天要为Facebook旗下各种应用处理超过10亿次NLP任务,Facebook AI的工业级NLP开源框架.(简化部 ...

  8. 【bzoj题解】1008 越狱

    题目描述 监狱有连续编号为1...N的N个房间,每个房间关押一个犯人,有M种宗教,每个犯人可能信仰其中一种.如果相邻房间的犯人的宗教相同,就可能发生越狱,求有多少种状态可能发生越狱. 输入 输入两个整 ...

  9. Linux下编译安装qemu和libvirt【转】

    转自:http://www.cnblogs.com/findumars/p/5679742.html 目录 [hide] 1 安装qemu 1.1 qemu介绍 1.2 下载源文件 1.3 编译安装 ...

  10. 移动端测试===PROC系列之---/proc/pid/stat 如何准确取cpu的值【转】

         /proc/ /stat 包含了所有CPU活跃的信息,该文件中的所有值都是从系统启动开始累计到当前时刻. [root@localhost ~]# cat /proc/6873/stat 68 ...