mysql order by int_mysql order by是怎么工作的?

假设我们要查询一个市民表中城市=杭州的所有人的名字,并且按照名字排序

CREATE TABLE `t` (

`id` int(11) NOT NULL,

`city` varchar(16) NOT NULL,

`name` varchar(16) NOT NULL,

`age` int(11) NOT NULL,

`addr` varchar(128) DEFAULT NULL,

PRIMARY KEY (`id`),

KEY `city` (`city`)

) ENGINE=InnoDB;

那么sql语句可以这样写

select city,name,age from t where city='杭州' order by name limit 1000 ;

接下来我们看下explain的结果

图中的Extra这一列下面的Using filesort表示需要排序,MySQL会为每个连接分配一块内存用于排序,就是sort_buffer,sort_buffer_size可以调整该排序内存大小

因为我们where条件用到了city,所以我们在city上面建立了索引

我们先看下该索引结构

从图中可以看出满足city=杭州的条件是ID_X到ID_Y之间的数据

通常情况下这个语句的执行流程如下:

1.初始化sort_buffer,确定放入name,age,city三个字段

2.从索引city中找到第一个符合条件的数据,也就是ID_X这个

3.取出索引中id的值,回表查询name,age,city的数据放入sort_buffer中

4.从索引city取下一个符合条件的id

5.重复步骤3,4直到city的值不满足city=杭州的条件,也就是图中ID_Y

6.对sort_buffer中的数据按照name排序

7.按照排序结果取前1000行数据返回给客户端

我们把这个排序过程叫全字段排序

如下图所示

上图按name排序这个动作可能在内存中完成也可能需要外部排序,这取决于排序需要的内存大小和sort_buffer_size这个参数

如果排序需要的内存大于sort_buffer_size设置的数值,那么就需要使用磁盘临时文件辅助排序

rowid排序

在上面的那个全字段排序中,只对原表查询了一次,但是如果查询的字段很多的话,那么sort_buffer中就会很多数据,就会使用到

磁盘临时辅助文件排序,这样性能会变差。

那么如果mysql认为单行数据过大会怎么办呢?

接下来设置一下这个参数为16

max_length_for_sort_data这个参数是mysql专门用来控制用于排序的行数据的单行的长度的一个参数,如果单行数据的字段的长度超过这个参数设置的值

那么就会使用rowid排序,比如说我们这个例子中name,age,city这三个字段的单行数据长度之和要是大于16,那么就会使用rowid排序

排序流程:

1.初始化sort_buffer,确定放入id,name

2.取出city索引中第一个满足条件的索引的id值

3.到主键id索引里面取出整行,取出name,id字段放入sort_buffer

4.去下一个符合条件的索引记录,放入sort_buffer中

5.重复步骤3.4直到不满足city=杭州

6.对sort_buffer中的数据按照name进行排序

7.遍历排序结果取出前1000行的数据的id,去表中查询出name,age,city返回给客户端

可以看出来rowid排序比全字段排序多了一次表查询就是步骤7

我们来对比下这两个排序

如果mysql觉得内存不够用就会用到rowid排序,如果内存够用则用全字段排序

也就是说Mysql有个设计思想,就是如果内存够,就尽量用内存,尽量减少磁盘的访问

看到这里你是不是觉得Mysql排序是一个非常复杂的流程,性能会不好,那么是不是所有的order_by语句都要排序呢?

不是的,如果需要排序的字段天然就是有序的,那么就不需要排序,啥意思呢,比如说我们建立一个city和name的联合索引

alter table t add index city_user(city, name);

作为与city索引的对比,我们看看这个索引

如果建立了这个索引那么执行流程就变成了这样

1.查询出第一条联合索引中city,name里面city=杭州的数据的id值

2.到主键索引里面取出整行,取出name,age,city字段

3.从索引city,name去下一个记录主键id

4.重复步骤2,3直到查到1000条记录或者不符合city=杭州循环结束

可以看到这个过程不需要排序,也不需要用到临时表

用explain验证一下

那么这个语句还有没有优化空间呢?

有的

我们建立一个三个字段的联合索引

alter table t add index city_user_age(city, name, age);

那么流程就变成了这样

1.查询出索引中第一条符合条件的数据,取出city,name,age作为结果集的一部分直接返回

2.从索引继续取下一个符合条件的数据作为结果集的一部分直接返回

3.重复步骤2直到查到1000条记录或者不符合city=杭州循环结束

这里其实就是用到了覆盖索引,直接不用回表查询了

当然这里绝对不是说遇到问题就加索引,这里只是举个例子,因为毕竟维护索引也是有代价的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/364238.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

URL模块之parse方法

url.parse(urlString , boolean , boolean) parse这个方法可以将一个url的字符串解析并返回一个url的对象。 参数: urlString指传入一个url地址的字符串第二个参数(可省)传入一个布尔值,默认为false,为true时&#x…

git使用学习笔记

## 关于Git Workspace:工作区 Index / Stage:暂存区 Repository:仓库区(或本地仓库) Remote:远程仓库##一、新建代码库# 在当前目录新建一个Git代码库$ git init # 新建一个目录,将其初始化为Gi…

over(partition by)开窗函数的使用

开窗函数是分析函数中的一种,开窗函数与聚合函数的区别是:开窗函数是用于计算基于组的某种聚合值且每个的组的聚合计算结果可以有多行,而聚合函数每个组的聚合计算结果只有一个。使用开窗函数可以在没有group by语句的情况下计算聚合值并将结…

发配边疆

这次要去清朝发家的地方,宣统皇帝待过的长春城一去,怕要2个年头才能回来了!朋友们临行前给我发了许多有趣的东东感觉颇深,明天发上来纪念下。有帮朋友的感觉真的很好啊!今天和女友通电话了,忽然有了从前的那…

在Java EE 7和WildFly中使用Bean验证来验证JAX-RS资源数据

我过去已经两次接触过这个主题。 首先,在我的文章《 在Java EE 6中将Bean验证与JAX-RS集成》中 ,介绍了甚至在Java EE平台规范中未定义之前,如何在JBoss AS 7中将Bean验证与JAX-RS结合使用的方法。 后来,在一篇为《 JAX Magazine …

EventUtil.addHandler方法

EventUtil.addHandler:addHandler 方法,职责是分别视情况而定来使用DOM0级方法、DOM2级方法或IE方法来添加事件。 这个方法属于一个名字叫EventUtil的对象,可以使用这个对象来处理浏览器间的差异。     addHandler() 方法…

Linux scp 指令

scp指令可从远程服务器下载文件或上传文件至远程服务器(适用于: mac没安装ftp软件临时使用) 上传: scp 本地文件路径 rootIP:远程路径 例: scp /Users/xxx/Downloads/email.png rootxxx.xxx.xxx.xx:/root/img 下载:scp rootxxx.xxx.xxx.xx:/root/img/email.png /Users/xxx/Down…

mysql游标遍历数据库_MySQL数据库中,使用游标循环遍历_MySQL

/*对*dt库下的所有数据表删除docuemttype为空和documenttype为MD,PD,ET的数据&#xff1a;delete from 表名 where length(documenttype)<2 or documenttype is null or documenttype in (et,md,pd);*/DELIMITER $$USE 数据库名称1$$DROP PROCEDURE IF EXISTS 存储过程名称1…

RN启动报错,环境相关问题

启动RN的时候刚开始报错&#xff1a; The request was denied by service delegate (SBMainWorkspace) for reason: Security ("Entitlement "com.apple.frontboard.debugapplications" required to launch applications for debugging"). 查询网络上的解决…

在Spring MVC Web应用程序中添加社交登录:集成测试

我已经写了关于为使用Spring Social 1.1.0的应用程序编写单元测试的挑战&#xff0c;并为此提供了一种解决方案 。 尽管单元测试很有价值&#xff0c;但是它并不能真正告诉我们我们的应用程序是否正常运行。 这就是为什么我们必须为此编写集成测试的原因 。 这篇博客文章可以…

js基本包装类型和引用类型

回顾 1.什么是基本类型&#xff1f; 共5个。boolean,string,number,null,undefined. 2.什么是引用类型&#xff1f; 引用类型的值是对象&#xff0c;保存在堆内存中&#xff1b; 引用类型的变量实际上是一个指针&#xff0c;它保存在栈中&#xff0c;指向堆内存中的对象&am…

mysql数据库套件_MySQL数据库管理开发套件(EMS SQL Management Studio For MySQL)下载 v1.3.0.46170 官方版 - 比克尔下载...

EMS SQL Management Studio For MySQL是一个强大的MySQL数据库管理和开发套件&#xff0c;由很多工具组成&#xff0c;涉及MySQL数据库管理、导入、导出、迁移、测试、备份、比较、同步等数据库管理和开发中需要的绝大部分功能&#xff0c;为开发人员提供了一个MySQL数据库管理…

异步和多线程

异步是目的&#xff0c;而多线程是实现这个目的的方法。 异步&#xff08;目的&#xff09;&#xff1a;由系统决定何时&#xff0c;如何去执行&#xff0c;非阻塞的&#xff0c;执行后回调。 CPU可以从线程池中获取一个线程资源&#xff0c;执行操作&#xff0c;并在执行完成后…

vue.config.js配置别名alias、配置生产环境清除console

项目中使用引入文件有时候路径比较深&#xff0c;需要使用"../../../xx.js"这种类似的路劲引入&#xff0c;这种方式比较笨&#xff0c;可以使用webpack的别名alias配置来解决。 首先&#xff0c;先确定项目中是否有path模块&#xff1a; 如果没有path模块需要先安装…

借助Java 8和lambdas,可以一起使用AssertJ和Awaitility

AssertJ和Awaitility是在自动代码测试中使用的两个我最喜欢的工具。 不幸的是直到最近&#xff0c;还不能一起使用它。 但是随后Java 8进入了游戏&#xff0c;几十行代码足以使其在Awaility 1.6.0中实现。 AssertJ提供了一组丰富的断言&#xff0c;其中包含非常有用的错误消息…

小程序-冒泡事件

小程序冒泡事件与非冒泡事件 会随之触发父元素的称为冒泡事件&#xff0c;反之&#xff0c;则是非冒泡事件 wxml&#xff1a; <view class"view1" bindtap"view1click"> <!-- 用 bind 绑定事件 -->view1<view class"view2" bin…

ruhr启动mysql数据库_Mysql表类型(存储引擎)的选择

以下内容转载自&#xff1a;https://www.cnblogs.com/jswang/p/6923911.html7.1 mysql存储引擎概述插件式存储引擎是mysql数据库最重要的特性之一&#xff0c;用户可以根据应用的需要选择ruhr存储和索引数据&#xff0c;是否使用事务等。InnoDB和BDB提供事务安全表&#xff0c;…

【JOURNAL】好久了啊

40天没有blog了&#xff0c;史无前例。项目、个人、朋友等等事情都同时很多&#xff0c;一根蜡烛3头点。这个星期还参加了一个5天的封闭workshop&#xff0c;加上这个酒店上网还贵得疯狂&#xff0d;&#xff0d;1块钱1分钟&#xff0d;&#xff0d;是的&#xff0c;你没有看错…

01 辅助函数之加密函数

常用的加密算法 常见的对称加密算法有 AES、DES、3DES 和 Itsdangerous &#xff0c;md5 &#xff0c;base64 Itsdangerous 加密和解密方法 2 from itsdangerous import TimedJSONWebSignatureSerializer as serializer3 class ItsdangerouSecret:4 # 初始化5 def __in…

mysql导出表结构 创建_mysql如何导出表结构为文本文件

Log Goup ID&#xff0c;可能会配置多个redo组&#xff0c;每个组对应一个id&#xff0c;当前都是0&#xff0c;占用4字节Start LSN&#xff0c;这个redo log文件开始日志的lsn&#xff0c;占用8字节Log File Number&#xff0c;总是为0&#xff0c;占用4字节Created By&#x…