iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >MySQL中如何优化order by语句
  • 194
分享到

MySQL中如何优化order by语句

MySQL优化orderby优化orderby 2023-01-12 15:01:06 194人浏览 安东尼
摘要

order by 查询语句使用也是非常频繁,有时候数据量大了会发现排序查询很慢,本文就介绍一下 Mysql 是如何进行排序的,以及如何利用其原理来优化 order by 语句。 建立一张表: CREATE TABLE `

order by 查询语句使用也是非常频繁,有时候数据量大了会发现排序查询很慢,本文就介绍一下 Mysql 是如何进行排序的,以及如何利用其原理来优化 order by 语句。

建立一张表:

CREATE TABLE `cc4` (
  `id` INT(11) NOT NULL,
  `user_name` VARCHAR(16) NOT NULL,
  `job` VARCHAR(16) NOT NULL,
  `company` VARCHAR(16) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `company_index` (`company`)
) ENGINE=INNODB;

建完表之后,再创建一个脚本,在脚本中插入 2000 条数据到前面建好的表cc4 中:

DROP PROCEDURE IF EXISTS cc4_data;
DELIMITER ;;
CREATE PROCEDURE cc4_data()
BEGIN
  DECLARE i INT;
  DECLARE company VARCHAR(128);
  SET i=1;
  WHILE(i<=2000) DO
    IF i%6 = 0
      THEN SET company= '证券';
    ELSEIF i%6 = 1
      THEN SET company= '银行';
    ELSEIF i%6 = 2
      THEN SET company= '保险';
    ELSEIF i%6 = 3
      THEN SET company= '科技';
    ELSEIF i%6 = 4
      THEN SET company= '金融';
    ELSE
      SET company ='传统';
    END IF;
    INSERT INTO cc4 VALUES(i, CONCAT('孤狼',i), CONCAT('程序员',i),company);
    SET i=i+1;
  END WHILE;
END;;
DELIMITER ;
CALL cc4_data();

这时候我们如果想要对某一家公司里面的人按照名字进行排序,一般会这么写:

SELECT user_name,job,company FROM cc4 WHERE company='科技' ORDER BY user_name LIMIT 1000;

这是一条非常简单且常见的 sql 语句,但是就是这么简单的一条 sql,它到底是如何被执行的呢?

全字段排序法

首先我们对上面的语句执行 explain 语句,看看是怎么执行的:

explain SELECT user_name,job,company FROM cc4 WHERE company='科技' ORDER BY user_name LIMIT 1000;

在这里插入图片描述

可以看到,在最后一列 Extra 中显示 Using filesort,也就是说用到了文件排序,这个文件排序是如何执行的呢?

大概画出如下一个草图表示表 cc4 中的索引示意图:

在这里插入图片描述

上图中显示 company 字段为普通索引,再加上主键索引,这张表一共有两个索引,所以这条语句是这么执行的:

  • 初始化 sort_buffer,并确定好需要放入 user_name ,job,company 这三个字段。
  • 从 company 索引中找到第一个满足 company='科技’ 条件的主键 id,也就是上图中的 ID-3。
  • 然后执行回表操作,根据 id 值到主键索引中取出整行,然后取出 user_name ,job,company 三个字段的值,并存入sort_buffer 中。
  • 从 company 索引中取下一个满足条件记录的主键 id,重复步骤 3 。
  • 继续重复 步骤 4 和 3,直到 company 的值不满足查询条件为止。
  • 对 sort_buffer 中的数据按照字段 user_name 做快速排序,最后按照排序结果取前 1000 行返回给客户端。

这种排序方式称之为全字段排序法。

上面步骤中的第 6 步,排序可以在内存中进行,如果内存足够的话,而内存是否足够则取决于 sort_buffer_size 的值,但是我们想一下,如果排序的数据量太大,我们不可能提供足够的内存,那么这时候就不得不使用磁盘的临时文件来进行排序。

那么我们如何知道当前的排序语句是使用文件完成排序还是使用内存来完成排序呢?

接下来我们执行下面两句话:

SET optimizer_trace='enabled=on';-- 打开optimizer_trace,只对本线程有效
SELECT user_name,job,company FROM cc4 WHERE company='科技' ORDER BY user_name LIMIT 1000;
SELECT * FROM `infORMation_schema`.`OPTIMIZER_TRACE`\G -- 查看 OPTIMIZER_TRACE 输出

最后这条查询语句会返回非常多的信息,包括了具体的查询步骤,我们看到最后的 filesort_summary:

在这里插入图片描述

这里面有几个信息比较关键:

  • memory_available:表示当前可以用于排序的内存
  • num_rows_found:表示有多少条数据参与排序。
  • num_initial_chunks_spilled_to_disk:表示产生了多少个临时文件用于排序,0表示当前是全部采用内存排序,这里为什么会产生多个文件的原因是当数据量过大时,mysql会分散到多个文件进行处理,最后通过归并排序算法来完成完整的排序。
  • sort_mode:最后这一列代表当前排序模式,packed_additional_fields代表的就是采用了全字段排序法,而且启用了 pack。

接下来我们把默认的排序内存改小一点:

SET sort_buffer_size=32768; -- 8.0 版本最小值,无法设置成更小,不同版本之间有差异
show variables like 'sort_buffer_size';

执行之后可以看到排序大小已经被修改为 32k:

在这里插入图片描述

接下来我们再来执行排序查询跟踪

SELECT user_name,job,company FROM cc4 WHERE company='科技' ORDER BY user_name LIMIT 1000;
SELECT * FROM `information_schema`.`OPTIMIZER_TRACE`\G -- 查看 OPTIMIZER_TRACE 输出

这时候会发现这时候使用到了 6 个临时文件进行排序:

在这里插入图片描述

主键排序法

在前面的全字段排序法中其实有些浪费,因为排序只用到了 user_name 字段,而我们却同时查询了其他字段,这些字段查询出来都是会占用空间的,尤其是当查询的字段很多,或者有些字段又特别长的时候,会占用很大空间,导致不得不使用文件排序,而由于字段多又长,就会造成文件个数增多,从而导致排序性能会更差。

上面的查询语句中,我们有没有办法不把一些无用的字段也放到 sort_buffer 中呢?

在 MySQL 中提供了一个字段 max_length_for_sort_data,默认是 4096

show variables like 'max_length_for_sort_data';

这个字段是控制用于排序的行数据的长度的一个参数。如果用于排序的单行数据长度超过这个值,MySQL 就认为单行数据太大了,要换一个算法,采用 rowid 算法。

采用 rowid 算法的步骤如下:

  • 初始化 sort_buffer,并确定好需要放入 user_name ,id 这两个字段。
  • 从 company 索引中找到第一个满足 company='科技’ 条件的主键 id,也就是上图中的 ID-3。
  • 然后执行回表操作,根据 id 值到主键索引中查找出整行数据,然后取出 user_name ,id 这两个字段的值,并存入sort_buffer 中。
  • 从 company 索引中取下一个满足条件记录的主键 id,重复步骤 3 。
  • 继续重复 步骤 4 和 3,直到 company 的值不满足查询条件为止。
  • 对 sort_buffer 中的数据按照字段 user_name 做快速排序。
  • 遍历排序结果,取前 1000 行数据,并根据主键 id 进行回表查询,取出 user_name,job 和 company三个字段返回给客户端。

这种排序方式对比前面一种全字段排序,我们发现存的数据更少了,所以需要的内存空间更少,但是又有一个更大的问题就是这里需要进行两次回表操作,当数据量过大,这也会造成性能影响。

所以我们再结合前面学习的知识,如果排序的时候可以采用覆盖索引,那么就不需要进行回表操作,从而大幅度提升性能,这也是覆盖索引的威力。

如何避免 filesort

首先我们看下面一个例子,执行以下语句:

DROP INDEX company_index ON cc4;-- 删除索引
CREATE INDEX company_user_index ON cc4 (company,user_name);-- 创建联合索引
explain SELECT user_name,job,company FROM cc4 WHERE company='科技' ORDER BY user_name LIMIT 1000;

执行结果如下:

在这里插入图片描述

可以看到,这次就没有用到 filesort 了,这是为什么呢?

因为我们创建了一个联合索引,而 MySQL 中的 B+ 树索引是天然有序的,所以当指定了 company,按顺序找到的数据,就是按照 user_name 进行的排序,也就不需要再执行一次排序操作了。

到此这篇关于MySQL中如何优化order by语句的文章就介绍到这了,更多相关MySQL优化order by内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

您可能感兴趣的文档:

--结束END--

本文标题: MySQL中如何优化order by语句

本文链接: https://www.lsjlt.com/news/177564.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • MySQL中如何优化order by语句
    order by 查询语句使用也是非常频繁,有时候数据量大了会发现排序查询很慢,本文就介绍一下 mysql 是如何进行排序的,以及如何利用其原理来优化 order by 语句。 建立一张表: CREATE TABLE `...
    99+
    2023-01-12
    MySQL优化orderby 优化orderby
  • 如何在Mysql中优化order by语句
    这篇文章给大家介绍如何在Mysql中优化order by语句,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。MySQL中的两种排序方式1.通过有序索引顺序扫描直接返回有序数据因为索引的结...
    99+
    2024-04-02
  • 如何优化sql中order By语句
    这篇文章主要介绍“如何优化sql中order By语句”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“如何优化sql中order By语句”文章能帮助大家解决问题。在...
    99+
    2024-04-02
  • MySQL中怎么利用索引优化ORDER BY排序语句
    MySQL中怎么利用索引优化ORDER BY排序语句,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。 1、ORDER BY的索...
    99+
    2024-04-02
  • MySQL中如何优化Order By Rand()效率
    这篇文章主要介绍了MySQL中如何优化Order By Rand()效率,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。 最近由于需要大概研...
    99+
    2024-04-02
  • 如何进行MySQL中的order by 优化
    这篇文章将为大家详细讲解有关如何进行MySQL中的order by 优化,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。 一 前言...
    99+
    2024-04-02
  • MySQL中(JOIN/ORDER BY)语句的查询过程及优化方法
    在MySQL查询语句过程和EXPLAIN语句基本概念及其优化中介绍了EXPLAIN语句,并举了一个慢查询例子: 可以看到上述的查询需要检查1万多记录,并且使用了临时表和filesort排序,这样的查询在用...
    99+
    2024-04-02
  • MySQL中Order By索引的优化
    本篇内容介绍了“MySQL中Order By索引的优化”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! 在...
    99+
    2024-04-02
  • Oracle中如何优化connect by语句
    Oracle中如何优化connect by语句,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。执行SQL:SELECT A...
    99+
    2024-04-02
  • like order by top组合语句的优化是怎样的
    今天就跟大家聊聊有关like order by top组合语句的优化是怎样的,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。环境信息基本信息操作系统:...
    99+
    2024-04-02
  • mysql查询语句group by和order by的使用
    这篇文章主要讲解了“mysql查询语句group by和order by的使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“mysql查询语句group b...
    99+
    2024-04-02
  • 【MySQL】order by 原理以及优化
    一 简介    偏向于业务的(MySQL)DBA或者业务的开发者来说,order by 排序是一个常见的业务功能,将结果根据指定的字段排序,满足前端展示的需求。然而排序操作也是经常出现慢...
    99+
    2024-04-02
  • mysql中order by如何用
    本篇内容主要讲解“mysql中order by如何用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“mysql中order by如何用”吧! ...
    99+
    2024-04-02
  • mysql织梦索引优化之MySQL Order By索引优化
    在一些情况下,MySQL可以直接使用索引来满足一个ORDER BY 或GROUP BY 子句而无需做额外的排序。尽管ORDER BY 不是和索引的顺序准确匹配,索引还是可以被用到,只要不用的索引部分和所有的额外的ORDER B...
    99+
    2024-04-02
  • MySQL中Order By如何使用
    这篇文章将为大家详细讲解有关MySQL中Order By如何使用,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。 ORDER BY uid ASC 按照u...
    99+
    2024-04-02
  • MySQL中ORDER BY子句有什么用?
    MySQL ORDER BY 子句用于指定查询结果的排序。关键字 ORDER BY 后面必须跟有我们要排序的列的名称。例如,我们要根据“价格”列对名为“ratelist”的下表进行排序 - mysql> Select * ...
    99+
    2023-10-22
  • MySQL中如何优化orderby语句
    order by 查询语句使用也是非常频繁,有时候数据量大了会发现排序查询很慢,本文就介绍一下 MySQL 是如何进行排序的,以及如何利用其原理来优化 order by 语句。 建立...
    99+
    2023-01-12
    MySQL优化order by 优化order by
  • MySQL中order by排序语句的原理是什么
    本文小编为大家详细介绍“MySQL中order by排序语句的原理是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“MySQL中order by排序语句的原理是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入...
    99+
    2023-07-04
  • MySQL order by与group by查询优化实现详解
    目录前言where与order by满足最左匹配法则中间断裂大哥不在范围失效order by 次序相反覆盖索引filesort的两种算法group by前言 order by满足两种情况,会使用 index 方...
    99+
    2024-04-02
  • MySQL中join语句如何优化
    今天小编给大家分享一下MySQL中join语句如何优化的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。Simple Neste...
    99+
    2023-07-05
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作