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

MySQL中如何优化orderby语句

MySQL优化orderby优化orderby 2023-01-12 18:01:29 333人浏览 八月长安
摘要

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

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中如何优化orderby语句

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

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

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

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

下载Word文档
猜你喜欢
  • MySQL中如何优化orderby语句
    order by 查询语句使用也是非常频繁,有时候数据量大了会发现排序查询很慢,本文就介绍一下 MySQL 是如何进行排序的,以及如何利用其原理来优化 order by 语句。 建立...
    99+
    2023-01-12
    MySQL优化order by 优化order by
  • MySQL中join语句如何优化
    今天小编给大家分享一下MySQL中join语句如何优化的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。Simple Neste...
    99+
    2023-07-05
  • MySQL语句如何优化
    MySQL语句如何优化,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。  开启慢查询日志,配置样例:  [mysqld] log-slow-qu...
    99+
    2024-04-02
  • MySQL中如何优化查询语句
    今天就跟大家聊聊有关MySQL中如何优化查询语句,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。  首先看一下分页的基本原理:  > expla...
    99+
    2024-04-02
  • MySQL中如何优化order by语句
    order by 查询语句使用也是非常频繁,有时候数据量大了会发现排序查询很慢,本文就介绍一下 mysql 是如何进行排序的,以及如何利用其原理来优化 order by 语句。 建立一张表: CREATE TABLE `...
    99+
    2023-01-12
    MySQL优化orderby 优化orderby
  • 在MySQL中如何优化SQL语句
    这篇文章主要介绍“在MySQL中如何优化SQL语句”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“在MySQL中如何优化SQL语句”文章能帮助大家解决问题。1.概述在应用系统开发过程中,由于初期数据量...
    99+
    2023-06-29
  • 如何在Mysql中优化order by语句
    这篇文章给大家介绍如何在Mysql中优化order by语句,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。MySQL中的两种排序方式1.通过有序索引顺序扫描直接返回有序数据因为索引的结...
    99+
    2024-04-02
  • mysql的sql语句如何优化
    要优化MySQL的SQL语句,可以采取以下几个方法:1. 使用索引:使用适当的索引可以大大提高查询性能。可以使用`EXPLAIN`命...
    99+
    2023-09-27
    mysql sql
  • 如何实现MySQL中优化表的语句?
    《MySQL优化表的语句及具体代码示例》在日常的数据库管理中,优化MySQL表的性能是非常重要的。通过优化表的语句,可以提高查询和更新的速度,减少资源的占用,提高系统的性能。本文将介绍如何通过具体的代码示例来优化MySQL表的性能。优化表结...
    99+
    2023-11-08
    实现 (Implement) MySQL (MySQL) 优化表 (Optimize)
  • MySQL中的join语句算法如何优化
    本篇内容主要讲解“MySQL中的join语句算法如何优化”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“MySQL中的join语句算法如何优化”吧!一、join语...
    99+
    2024-04-02
  • mysql语句的优化
    本篇内容介绍了“mysql语句的优化”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! MySQL客...
    99+
    2024-04-02
  • 如何优化SQL语句
    这篇文章主要介绍“如何优化SQL语句”,在日常操作中,相信很多人在如何优化SQL语句问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何优化SQL语句”的疑惑有所帮助!接下来,...
    99+
    2024-04-02
  • MySQL中join语句怎么优化
    目录Simple Nested-Loop Joinblock Nested-Loop JoinIndex Nested-Loop Join如何选择驱动表?Simple Nested-Loop Join 我们来看一下当进行...
    99+
    2023-03-03
    MySQLjoin优化 MySQLjoin语句
  • MySQL之优化SELECT语句
    MySQL之优化SELECT语句 文章目录 MySQL之优化SELECT语句摘要:引言:1. MySQL性能提成优化概述2. WHERE子句优化3. 范围优化4. 哈希联接优化5. 储存引擎下的优化6. 索引条件下推优化7....
    99+
    2023-08-16
    mysql 数据库 原力计划
  • Mysql 优化LEFT JOIN语句
    1.首先说一下个人对LEFT JOIN 语句的看法,原先我是没注意到LEFT JOIN 会影响到性能的,因为我平时在项目开发中,是比较经常见到很多个关联表的语句的。 2.阿里巴巴手册说过,连接表的语句...
    99+
    2023-08-31
    mysql 数据库
  • 如何优化sql中order By语句
    这篇文章主要介绍“如何优化sql中order By语句”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“如何优化sql中order By语句”文章能帮助大家解决问题。在...
    99+
    2024-04-02
  • Oracle中如何优化connect by语句
    Oracle中如何优化connect by语句,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。执行SQL:SELECT A...
    99+
    2024-04-02
  • MySQL中怎么优化查询语句
    这篇文章将为大家详细讲解有关MySQL中怎么优化查询语句,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。  MySQL常用30种SQL查询语句优化方法  1、...
    99+
    2024-04-02
  • 如何优化MySQL数据库中的SQL语句性能?
    如何优化MySQL数据库中的SQL语句性能?概述:MySQL是目前最常用的关系型数据库管理系统之一,它的性能影响着许多应用程序的运行效率。在开发和维护MySQL数据库时,优化SQL语句的性能是至关重要的。本文将介绍一些优化MySQL数据库中...
    99+
    2023-12-17
    MySQL 优化 SQL语句性能
  • MySQL语句的优化方法
    本篇内容主要讲解“MySQL语句的优化方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“MySQL语句的优化方法”吧! 1.建立基准,建立基准,建立基...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作