在上一篇文章MySQL查询语句执行过程及性能优化-基本概念和EXPLAIN语句简介中介绍了EXPLAIN语句,并举了一个慢查询例子:

可以看到上述的查询需要检查1万多记录,并且使用了临时表和filesort排序,这样的查询在用户数快速增长后将成为噩梦。

在优化这个语句之前,我们先了解下SQL查询的基本执行过程:

*)应用通过MySQL API把查询命令发送给MySQL服务器,然后被解析

*)检查权限、MySQL optimizer进行优化,经过解析和优化后的查询命令被编译为CPU可运行的二进制形式的查询计划(query plan),并可以被缓存

*)如果存在索引,那么先扫描索引,如果数据被索引覆盖,那么不需要额外的查找,如果不是,根据索引查找和读取对应的记录

*)如果有关联查询,查询次序是扫描第一张表找到满足条件的记录,按照第一张表和第二张表的关联键值,扫描第二张表查找满足条件的记录,按此顺序循环

*)输出查询结果,并记录binary logs

显然合适的索引将大大简化和加速查找。再看一下上面那条查询语句,除了条件查询外,还有关联查询以及ORDER BY即排序操作,

那么让我们进一步了解下关联查询(JOIN)和ORDER BY是怎么工作的,MySQL有三种方式来处理关联查询和数据排序:

第一种方法是基于索引,第二种是对第一个非常量表进行filesort(quicksort),还有一种是把联合查询的结果放入临时表,然后进行filesort。

  1. 注1:关于什么是非常量表,请参考阅读MySQL开发手册:Consts and Constant Tables,
  2. 注2:什么是filesort呢,这不是字面意思的文件排序,filesort有两种模式:
  3. 1、模式1:排序后的元素涵盖了要输出的数据。排序结果是一串有序序列元素组,不再需要额外的记录读取;
  4. 2、模式2:排序结果是<sort_key,row_id>键值对序列,通过这些row_ids再去读取记录(随机读取,效率低下);
  5. 注3:关于什么是临时表,请参考阅读MySQL开发手册:How MySQL Uses Internal Temporary Tables

第一种方法用于第一个非常量表中存在ORDER BY所依赖的列的索引,那就可直接使用已经有序的索引来查找关联表的数据,这种方式是性能最优的,因为不需要额外的排序动作:

第二种方式用于ORDER BY所依赖的列全部属于第一张查询表且没有索引,那么我们可以先对第一张表的记录进行filesort(模式可能是模式1也可能是模式2),得到有序行索引,然后再做关联查询,filesort的结果可能是在内存中,也可能在硬盘上,这取决于系统变量sort_buffer_size(一般为2M左右):

第三种方法用于当ORDER BY的元素不属于第一张表时,需要把关联查询的结果放入临时表,最后对临时表进行filesort:

第三种方法中的临时表,可能是在内存中(in-memory table),也可能是在硬盘上,一般是下面两种情况会使用硬盘(on-disk table):

(1)使用了BLOB,TEXT类型的数据

(2)内存表占用超过了系统变量tmp_table_size/max_heap_table_size的限定(一般为16M左右),只能放在硬盘上

从上面的查询执行过程和方式,我们应该可以清楚的知道为什么Using filesort,Using temporary会严重的影响查询性能,因为如果数据类型或者字段设计有问题,

在需要查询的表以及结果中存在大数据的字段,而没有合适的索引可用时,都可能会导致产生大量的IO操作,这就是查询性能缓慢的根源所在。

回到文章开头所举的查询实例,它显然是使用了效率最低的第三种方法,我们需要做和尝试的优化手段有:

1、为users.fl_no添加索引,为select和where所使用的字段建立索引

2、把users.fl_no转移到或者作为冗余字段添加到表user_profile中

3、去除TEXT类型的字段,TEXT可以替换为VARCHAR(65535)或对于中文而言VARCHAR(20000)

4、如果实在无法消除Using filesort,那么提高sort_buffer_size,以减少IO操作负担

5、尽量使用第一张表所覆盖的索引进行排序,实在不行,可以把排序逻辑从MySQL中移到PHP/Java程序中执行

实施1、2、3的优化方法后,EXPLAIN结果如下:

备注:编写简单的PHP应用,用siege测试,查询效率提高>3倍。

MySQL查询语句执行过程及性能优化-查询过程及优化方法(JOIN/ORDER BY)的更多相关文章

  1. MySQL查询语句执行过程及性能优化(JOIN/ORDER BY)-图

    http://blog.csdn.net/iefreer/article/details/12622097 MySQL查询语句执行过程及性能优化-查询过程及优化方法(JOIN/ORDER BY) 标签 ...

  2. MySQL查询语句执行过程及性能优化-基本概念和EXPLAIN语句简介

    网站或服务的性能关键点很大程度在于数据库的设计(假设你选择了合适的语言开发框架)以及如何查询数据上. 我们知道MySQL的性能优化方法,一般有建立索引.规避复杂联合查询.设置冗余字段.建立中间表.查询 ...

  3. Mysql查询语句执行过程

    Mysql查询语句执行过程   Mysql分为server层和存储引擎两部分,或许可以再加一层连接层   连接层(器) Mysql使用的是典型的C/S架构.连接器通过典型的TCP握手完成连接. 需要注 ...

  4. [转]MySQL查询语句执行过程详解

    Mysql查询语句执行原理 数据库查询语句如何执行?语法分析:首先进行语法分析,对使用sql表示的查询进行语法分析,生成查询语法分析树.语义检查:检查sql中所涉及的对象以及是否在数据库中存在,用户是 ...

  5. sql语句执行顺序与性能优化(1)

    一.首先我们看一下mysql的sql语句的书写顺序 . select--distinct--from--on--where--group by--having--聚合函数cube.rollup--or ...

  6. python 3 mysql sql逻辑查询语句执行顺序

    python 3 mysql sql逻辑查询语句执行顺序 一 .SELECT语句关键字的定义顺序 SELECT DISTINCT <select_list> FROM <left_t ...

  7. mysql第四篇--SQL逻辑查询语句执行顺序

    mysql第四篇--SQL逻辑查询语句执行顺序 一.SQL语句定义顺序 SELECT DISTINCT <select_list> FROM <left_table> < ...

  8. mysql 中语句执行的顺序以及查询处理阶段的分析

    原文链接:http://www.php.cn/mysql-tutorials-408865.html 本篇文章给大家带来的内容是关于mysql中语句执行的顺序以及查询处理阶段的分析,有一定的参考价值, ...

  9. mysql优化必知(mysql的语句执行顺序)

    MySQL的语句执行顺序 MySQL的语句一共分为11步,如下图所标注的那样,最先执行的总是FROM操作,最后执行的是LIMIT操作.其中每一个操作都会产生一张虚拟的表,这个虚拟的表作为一个处理的输入 ...

随机推荐

  1. 【bzoj2875】 Noi2012—随机数生成器

    http://www.lydsy.com/JudgeOnline/problem.php?id=2875 (题目链接) 题意 求${X_{n}}$. Solution 矩乘板子,这里主要讲下会爆lon ...

  2. 解决360WiFi有时候手机连接不上

    有可能是无线网卡的问题: 右击“计算机”->选择“管理”->“设备管理器”->网络适配器->选择“Broadcom  802.11n 网络适配器”,或者你实在不知道哪个是无线网 ...

  3. A*算法–A* algorithm tutorial

    Author:Justin Heyes-Jones From: http://heyes-jones.com/astar.php Date:2014.8.16 本文地址:http://www.cnbl ...

  4. WINDOWS控制界面操作命令for WIN10

    Windows系统:开始--运行--命令大全: cmd--------CMD命令提示符 cleanmgr-------垃圾整理 compmgmt.msc---计算机管理 conf----------- ...

  5. 蓝桥杯 大臣的旅费_树的最长度_两次DFS

    #include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> ...

  6. scala 基础到高阶

    本文打算对这小段时间学习 scala 以及 spark 编程技术做个小结,一来温故而知新,而来为以后查阅方便 spark scala 入门小例子  文本文件 UserPurchaseHistory.c ...

  7. Does Deep Learning Come from the Devil?

    Does Deep Learning Come from the Devil? Deep learning has revolutionized computer vision and natural ...

  8. Flex 经验笔记一

    Module页面嵌套子Module页面直接用标签嵌入是不行的,无法显示出来,需要用到 ModuleManager 使用ModuleInfo 的 addEventListener 判断当子Module ...

  9. 仿QQ聊天图文混排流程图【适用于XMPP】

      图文混排流程图.graffle4.8 KB   下面附上图片素材: 表情.zip692.5 KB     下面是字符串与图片的详细对应关系:                 "[呲牙]& ...

  10. PHP删除数组中空值

    array_filter   函数的功能是利用回调函数来对数组进行过滤,一直都以为用回调函数才能处理, 却没有发现手册下面还有一句,如果没有回调函数,那么默认就是删除数组中值为false的项目 代码: ...