让order by、group by查询速度更快

1、引言1.1 MySQL的基本知识1.2 MySQL的优势

2、order by 原理2.1 MySQL的排序方式2.2 Filesort 在哪里完成排序2.3 Filesort 下的排序模式

3、order by 优化3.1 添加合适索引3.1.1 排序字段添加索引3.1.2 多个字段排序优化3.1.3 先等值查询再排序的优化

3.2 去掉不必要的返回字段3.3 修改参数

4、 group by 优化5、总结

1、引言

在结束性能知识分享,我们终于迎来了MySQL的 知识。 关于,MySQL的基本用法,小鱼也是整理的几篇文章,如: 《基本用法总括一》 《基本用法总括二》 《SQL去重查询数据》 《SQL语句多个表查询,inner join的用法》 《sql数据库中的 delete 与drop的区别》

接下来,小鱼会更详细的分享关于 MySQL的知识,包含这四大类: ①SQL优化 ②MySQL索引 ③MySQL锁 ④事务

接下来的很长一段时间, 就让小鱼陪着你, 一起把 MySQL的姿(知)势(识) 搞起来!!!

1.1 MySQL的基本知识

按照惯例,先介绍一下 MySQL基本知识:

MySQL 是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。 MySQL 的 SQL “结构化查询语言”,是用于访问数据库的最常用标准化语言。 MySQL 软件采用了 GPL(GNU 通用公共许可证),由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,许多中小型网站为了降低网站总体拥有成本,而选择 MySQL 作为其网站数据库。

1.2 MySQL的优势

MySQL的优势有哪些,我们来瞧瞧。

・MySQL开源的,无需支付额外费用的;

・MySQL使用标准的SQL数据语言形式;

・MySQL可以运行多个系统上,并支持多个语言(如:C、C++、Python、Java、Perl、PHP、Eiffel、Ruby 等);

・MySQL可以定制,采用 GPL 协议,可修改源码来开发自己的 MySQL 系统。

所以,我们要搞好MySQL数据库,是不是非常有必要。

今天, 我们就先从 order by和group by来说起。

2、order by 原理

为了更好,更容易理解相关知识点,咱先举个例子。

也是小鱼的一贯作风, 举例说话 !

先创建一张测试表,

/* auth:carl_DJ  */

/* 使用ClassDJ这个database */

use ClassDJ;

/* 如果表t1存在则删除表t1 */

drop table if exists t1;

/* 创建表t1 */

CREATE TABLE 't1'(

'id' int(11) NOT NULL AUTO_INCREMENT,

'a' int(20) DEFAULT NULL ,

'b' int(20) DEFAULT NULL ,

'c' int(20) DEFAULT NULL ,

'd' datetime NOT NULL  DEFAULT CURRENT_TIMESTAMP ,

PRIMARY KEY (`id`),

KEY `idx_a_b` (`a`,`b`),

KEY `idx_c` (`c`)

)    ENGINE=InnoDB CHARSET=utf8mb4 ;

/* 如果存在存储过程insert_t1,则删除 */

drop procedure if exists insert_t1;

delimiter ;;

/* 创建存储过程insert_t1 */

create procedure insert_t1()

begin

/* 声明变量i */

declare i int;

/* 设置i的初始值为1 */

set i=1;

/* 对满足i<=10000的值进行while循环 */

while(i<=10000)do

/* 写入表d1中a、b两个字段,值都为i当前的值 */

insert into t1(a,b,c) values(i,i,i);

/* 将i加1 */

set i=i+1;

end while;

end ;;

delimiter ;

/* 运行存储过程insert_t1 */

call insert_t1();

/* 将id大于9000的行的a字段更新为1000 */

update t1 set a=1000 where id >9000;

创建完表,我们就来研究一下MySQL的排序原理

2.1 MySQL的排序方式

按照排序原理分,MySQL 排序方式分两种:

①通过有序索引直接返回有序数据

②通过Filesort进行的排序

那么,问题来了,

如何确定某条排序的SQL所使用的排序方式?

答:使用explain来查看该排序SQL的执行计划,重点关注****字段。

★如果Extra字段里显示是 Using index,则表示是通过有序索引直接返回有序数据

例如;

explain select id,c from t1 order by c;

★如果Extra字段里显示是 Using filesort,则表示该 SQL 是通过 Filesort 进行的排序

例如:

explain select id,d from t1 order by d;

是不是,这就一目了然 了。 Nice

2.2 Filesort 在哪里完成排序

MySQL 中的 Filesort 并不一定是在磁盘文件中进行排序的,也有可能在内存中排序, 内存排序还是磁盘排序取决于排序的数据大小和 sort_buffer_size 配置的大小。

・如果 “排序的数据大小” < sort_buffer_size: 内存排序

・如果 “排序的数据大小” > sort_buffer_size: 磁盘排序

同样,问了又来了,

如何确定使用 Filesort 排序的 SQL 是在内存还是在磁盘中进行的排序操作?

答:使用 trace 进行分析重点关注 number_of_tmp_files,

★如果等于 0,则表示排序过程没使用临时文件,在内存中就能完成排序;

★如果大于0,则表示排序过程中使用了临时文件。

举例

一、未使用临时文件排序

上图中,因为 number_of_tmp_files 等于 0,表示未使用临时文件进行排序,所以是内存排序。

参数解析:

・rows:预计扫描的行数 ・examined_rows:参与排序的行 ・number_of_tmp_files:使用临时文件的个数 ・sort_buffer_size:sort_buffer 的大小 ・sort_mode:排序模式

二、使用临时文件排序

上图中,因为 number_of_tmp_files 等于 7,所以表示使用的是磁盘排序。

number_of_tmp_files 等于 7表示:

该SQL 将需要排序的数据分为 7 份,然后每份单独排序,再存放在 7 个临时文件中,最后把 7 个临时文件合并成一个大的有序文件。

2.3 Filesort 下的排序模式

一、排序模式 Filesort 下的排序模式有三种:

・< sort_key, rowid >双路排序(又叫回表排序模式):是首先根据相应的条件取出相应的排序字段和可以直接定位行数据的行 ID,然后在 sort buffer 中进行排序,排序完后需要再次取回其它需要的字段;

・< sort_key, additional_fields >单路排序:是一次性取出满足条件行的所有字段,然后在sort buffer中进行排序;

・< sort_key, packed_additional_fields >打包数据排序模式:与单路排序相似,区别是将 char 和 varchar 字段存到 sort buffer 中时,更加紧缩。

MySQL 通过比较系统变量 max_length_for_sort_data 的大小和需要查询的字段总大小来判断使用哪种排序模式

二、判断排序模式 通过 max_length_for_sort_data 的大小和需要查询的字段总大小来判断使用哪种排序模式。

・如果 max_length_for_sort_data 比查询字段的总长度大,那么使用 < **sort_key, additional_fields >**排序模式;

・如果 max_length_for_sort_data 比查询字段的总长度小,那么使用 排序模式。

三、实例举例

set session optimizer_trace="enabled=on",end_markers_in_json=on;

SET max_length_for_sort_data = 20;

/* 查询表d1的id、a、d三个字段的值,按照字段d进行排序  */

select a,d from t1 order by d;

SELECT * FROM information_schema.OPTIMIZER_TRACE\G

OPTIMIZER_TRACE 结果中排序信息,如下图:

可以看到,使用的是****排序模式。

② 我们要是变成 ,怎么整呢?

思路:因为 a、d 两个字段的总长度为 12,可以尝试把 max_length_for_sort_data 改为小于 12 的值,看排序模式是否有改变。

操作:

set session optimizer_trace="enabled=on",end_markers_in_json=on;

SET max_length_for_sort_data = 4;

/* 查询表d1的id、a、d三个字段的值,按照字段d进行排序  */

select a,d from t1 order by d;

SELECT * FROM information_schema.OPTIMIZER_TRACE\G

OPTIMIZER_TRACE 结果中排序信息,如下图:

看看,是不是变成 排序模式了。 非常Nice。

3、order by 优化

我们了解了order by的原理, 那么我们就来看看,优化order by 有什么技巧。

3.1 添加合适索引

3.1.1 排序字段添加索引

①首先我们看下对 d 字段(没有索引)进行排序的执行计划:

explain select d,id from t1 order by d;

执行结果如下:

发现使用的是 filesort(关注 Extra 字段)。

②再看些对 c 字段(有索引)进行排序的执行计划:

explain select c,id from t1 order by c;

执行结果如下:  可以看到,根据有索引的字段排序,在 Extra 中显示的就为 Using index,表示使用的是索引排序。

注:

如果数据量比较大,显然通过有序索引直接返回有序数据效率更高

3.1.2 多个字段排序优化

问:有时面对的需求是要对多个字段进行排序,而这种情况应该怎么优化或者设计索引呢?

答:如果多个字段排序,可以在多个排序字段上添加联合索引来优化排序语句

举个例子 ① 对 a、c 两个字段进行排序的执行计划

explain select id,a,c from t1 order by a,c;

执行结果如下:

观察 Extra 字段,发现使用的是 filesort。

② 再看对 a、b(a、b 两个字段有联合索引)两个字段进行排序。

explain select id,a,b from t1 order by a,b;

执行结果如下:  发现使用的是索引排序。

注:

多个字段排序的情况,如果要通过添加索引优化,得注意排序字段的顺序与联合索引中列的顺序要一致

3.1.3 先等值查询再排序的优化

问:我们更多的情况是会先根据某个字段条件查出一部分数据,然后再排序,而这类 SQL 应该如果优化呢?

答:可以通过在条件字段和排序字段添加联合索引来优化此类排序语句。

举个例子

① 表 d1中,根据 a=1000 过滤数据再根据 d 字段排序的执行计划如下:

explain select id,a,d from t1 where a=1000 order by d;

执行结果如下:  可以在 Extra 字段中看到 “Using filesort”,说明使用的是 filesort 排序。

② 再看下根据 a=1000 过滤数据在根据 b 字段排序的执行计划(a、b 两个字段有联合索引):

explain select id,a,b from t1 where a=1000 order by b;

执行结果如下:

可以在 Extra 字段中看到“Using index”,说明使用的是索引排序。

3.2 去掉不必要的返回字段

有时,我们其实并不需要查询出所有字段,但是,有的时候,我们习惯性的写出 “select * from table_name”。

举个例子

select * from t1 order by a,b;           /* 根据a和b字段排序查出所有字段的值 */

执行结果如下:

select id,a,b from t1 order by a,b;      /* 根据a和b字段排序查出id,a,b字段的值 */

执行结果如下:

通过这两个例子,我们可以看到, 查询所有字段的这条 SQL 是 filesort 排序, 而只查 id、a、b 三个字段的 SQL 是 index 排序。

那么,

为什么查询所有字段会不走索引?

是因为:

扫描整个索引并查找到没索引的行的成本比扫描全表的成本更高,所以优化器放弃使用索引。

3.3 修改参数

一、修改哪些参数? 这里就用到了在前面提到的两个参数:

max_length_for_sort_data sort_buffer_size。

二、如何修改这两个参数的值?

・max_length_for_sort_data: 如果觉得排序效率比较低,可以适当加大 max_length_for_sort_data 的值,让优化器优先选择全字段排序。当然不能设置过大,可能会导致 CPU 利用率过低或者磁盘 I/O 过高;

・sort_buffer_size: 适当加大 sort_buffer_size 的值,尽可能让排序在内存中完成。但不能设置过大,可能导致数据库服务器 SWAP。

4、 group by 优化

默认情况,会对 group by 字段排序, 因此优化方式与 order by 基本一致, 如果目的只是分组而不用排序,可以指定 order by null 禁止排序

5、总结

今天,整理的是 order by 和group by的 一些优化技巧, 因为在写sql中,这两个还是比较常用的, 所以,记住还是有必要的。

关于order by的优化,主要就这么几点知识:

・通过添加合适索引 ・去掉不必要的返回字段 ・调整参数:主要是 max_length_for_sort_data 和 sort_buffer_size

回顾一下,是不是很简单,也很Nice。 嗯,细细品,慢慢品! 接下来一段时间,小鱼都会分享更多更好玩的MySQL知识。 可要坚持撸SQL哦~

mysql order by file_深聊MySQL,从入门到入坟之:如何让order by、group by查询速度飞起来...相关推荐

  1. 深聊MySQL,从入门到入坟之:MySQL竟然也有后悔药!!!

    MySQL后悔药,防止看铁窗 1.引言 2.5种后悔药 2.1 limit 2.2 先测试后生产 2.3 删除前,先备份 2.4 删除前,先查询 2.5 修改时, begin+commit 3. 总结 ...

  2. MySql的入门到入坟

    系列文章目录 本章讲述Mysql的入门和使用. 文章目录 系列文章目录 前言 一.数据库设计分析 1. 软件开发周期 2. 设计数据库的步骤 3. 绘制E-R图 4. 数据库设计范式 二.MySql的 ...

  3. 我的linux学习之入门到入坟(二十二)-mysql基础(一)

    交流群:692356620,有不同的问题或见解可以来群里讨论,或者私聊我qq:1251611916 文章目录 交流群:692356620,有不同的问题或见解可以来群里讨论,或者私聊我qq:125161 ...

  4. mf怎么使mysql信息分区_细聊MySQL的分区功能

    此篇主要介绍下MySQL的分区功能.我们分别从分区的概念.分区对于MySQL应用的优点.分区的类别及设置来和大家一起探讨下MySQL的分区. 什么是分区? MySQL在未启用分区功能时,数据库的单个表 ...

  5. mysql mha管理平台_Jeson聊Mysql管理之道-MHA最全搭建步骤

    MHA是一套相对成熟的MySQL高可用方案,能做到在0~30s内自动完成数据库的故障切换操作,在master服务器不宕机的情况下,基本能保证数据的一致性. 一.常见部署架构模式 模式一.拿一台mysq ...

  6. MySQL学习笔记(一)—MySQL基础

    文章目录 一.MySQL基础及入门 1. MySQL的相关配置 1.1 MySQL的启动与关闭 1.1.1 方式一 : window服务启动 MySQL 1.1.2 方式二: DOS 命令方式启动 1 ...

  7. mysql text 查询速度_数据库学习之让索引加快查询速度(四)

    数据库学习之让索引加快查询速度 目录 索引简介 mysql的索引分类 创建索引 添加与删除索引 索引简介 索引在MySQL中也叫做"键",是存储引擎用于快速找到记录的一种数据结构. ...

  8. mysql执行底层_天天写order by,你知道Mysql底层如何执行吗?

    在实际的开发中一定会碰到根据某个字段进行排序后来显示结果的需求,但是你真的理解order by在 Mysql 底层是如何执行的吗? 假设你要查询城市是苏州的所有人名字,并且按照姓名进行排序返回前 10 ...

  9. mysql底层用什么写的_天天写order by,你知道Mysql底层如何执行吗?

    前言在实际的开发中一定会碰到根据某个字段进行排序后来显示结果的需求,但是你真的理解order by在 Mysql 底层是如何执行的吗? 假设你要查询城市是苏州的所有人名字,并且按照姓名进行排序返回前 ...

  10. mysql查询语句能否让一个字段不显示出来_天天写order by,你知道Mysql底层如何执行吗?

    作者:不才陈某 前言 在实际的开发中一定会碰到根据某个字段进行排序后来显示结果的需求,但是你真的理解order by在 Mysql 底层是如何执行的吗?假设你要查询城市是苏州的所有人名字,并且按照姓名 ...

最新文章

  1. boost log 能不能循环覆盖_前端基础进阶(十四):深入核心,详解事件循环机制...
  2. linux go 安装
  3. DB2sql——DB2临时表的创建
  4. 分析android动画模块
  5. kafka window 启动_Apache Flink结合Kafka构建端到端的Exactly-Once处理
  6. C++笔记-ClassA a和ClassA a()的区别与联系
  7. 2003 Server下隐藏帐号的建立
  8. Java延时队列DelayedQueue
  9. mysql foundrows 并发_MySQL 中的 FOUND_ROWS() 函数
  10. docker自动部署脚本
  11. 2021年计算机二级web题库,2021年全国计算机等级考试(二级Web程序设计)经典试题及答案...
  12. figtree需要在JAVA下运行吗,科学网—Inno setup 制作安装文件以编译FigTree为例 - 张金龙的博文...
  13. android平台数字看板,数据看板
  14. php随机点名代码怎么做,html座位表随机点名的实例代码
  15. 计算机鼠标老跳动,用win10系统,鼠标总是乱飞乱跳怎么回事,找到原因及解决方案了...
  16. Unity 之 ShaderGraph 模拟“吃鸡”海面效果入门级教程
  17. 使用libjpeg进行图片压缩
  18. 如何开发自己的通用Mapper
  19. 《SQL与关系数据库理论——如何编写健壮的SQL代码》一3.7 TABLE_DUM和TABLE_DEE
  20. 异或(XOR)运算加密/解密算法

热门文章

  1. Jmeter插件安装perfmon(服务器资源监控工具)
  2. vue中用cdn引入优化vender.js大小,和cdn 引入mint-ui的问题
  3. 劣币驱逐良币,人吃人的中国职场环境还能走多远
  4. graphql java如何使用_graphql-java使用手册:part10 如何落地应用(Application concerns)...
  5. 如何提升会员收入?从这道面试题谈谈框架思维。
  6. Sumatra PDF 缩放设置
  7. pmp项目管理师证书有用么?
  8. 2021年中国消费金融行业贷款情况及发展趋势分析:互联网消费金融放款规模达到20.2万亿[图]
  9. 2023-2028年中国压铸机行业发展前景与投资趋势分析报告
  10. CompletableFuture模拟复杂场景使用测试。。。