当前位置: 首页 > news >正文

第48讲:SQL优化之ORDER BY排序查询的优化

文章目录

    • 1.ORDEY BY排序查询优化方面的概念
    • 2.ORDER BY排序的优化原则
    • 3.ORDER BY排序优化的案例
      • 3.1.准备排序优化的表以及索引
      • 3.2.同时对nl和lxfs字段使用升序排序
      • 3.3.同时对nl和lxfs字段使用降序排序
      • 3.4.排序时调整联合索引中字段的位置顺序
      • 3.5.排序时一个字段使用升序一个字段使用降序
      • 3.6.解决两个字段不同排序规则出现Using filesort
    • 4.ORDER BY多字段多排序方式的索引结构图

1.ORDEY BY排序查询优化方面的概念

在MySQL数据库中,有两种排序类型:

  • Using filesort:
    • 通过表的索引或者全表扫描,读取满足条件的数据行,然后在排序缓冲区sortbuffer中完成排序的操作,所有不是通过索引直接返回的排序结果都是filesort排序,效率相对来说比较低。
    • 索引本身具有排序的功能,如果索引的排序没有满足我们的排序条件,此时读取到满足条件的数据后,还需要在缓冲区中重新排序,最后完成排序的操作,这类的排序都是filesort。
    • 就和回表查询一样,本来可以在二级索引中拿到数据,但是还需要走回表查询才能完成需求,filesort也一样,如果不能再索引排序中拿到结果,就需要在缓冲区中再次排序。
  • Using index:
    • 通过有序索引排序扫描后,直接就能返回有序的数据,满足排序需求,这类的排序都是using index,不需要额外的排序,效率很高。
    • 索引排序默认是ASC升序排序,如果我们的排序规则都是升序,并且排序的字段也是索引字段,此时就是using index排序。

对于这两种排序方式,Using index的性能最高,Using filesort的性能较低,我们再优化排序操作时,尽量的使用Using index。

索引的默认排序规则是升序排序,下面来观察几种排序需求,看看哪些是Using filesort,那些是Using index。

  • 当排序的字段都是升序时,排序方式就是Using index。

  • 当排序的字段都是降序时,排序方式就是Using index,因为还是在一个索引排序集里,只不过反向排序即可。

  • 当排序的字段一个是升序、一个是降序,此时就会出现Using filesort,因为第一个字段是升序,也是默认的规则,直接返回排序即可,但是第二个字段是降序,相当于又要重新读取一遍数据,然后拿到缓冲区里再次排序。

2.ORDER BY排序的优化原则

  • 将需要排序的字段建立联合索引,多字段排序时也是需要遵循最左前缀法则的。
  • 查询返回的字段尽量使用覆盖索引的字段,此时不需要回表查询,效率很高。
  • 多字段排序时,如果一个字段升序、一个字段降序,那么就在创建联合索引时,为字段设置排序规则。
  • 如果不能避免出现filesort,那么可以适当的增大排序缓冲区的大小,参数是sort_buffer_size,默认为256k。

3.ORDER BY排序优化的案例

3.1.准备排序优化的表以及索引

1)表数据

image-20220603141608777

2)索引

我们主要以nl和lxfs两个字段排序,将这两个字段创建一个联合索引。

mysql> create index idx_user_nl_lxfs on tb_user(nl,lxfs);

image-20220603141824047

3.2.同时对nl和lxfs字段使用升序排序

同时对nl和lxfs字段进行升序排序,观察执行计划中排序方式是什么。

mysql> explain select nl,lxfs from tb_user order by nl,lxfs;

根据执行计划的输出,我们可以看到同时对nl和lxfs字段进行升序排序时,都走了索引,排序方式是Using index,此时的效率最高。

image-20220603142641016

当然如果我们只根据nl排序,排序方式也是Using index,因为nl字段也在联合索引中。

image-20220603142626946

3.3.同时对nl和lxfs字段使用降序排序

同时对nl和lxfs字段进行降序排序,观察执行计划中的排序方式是什么。

mysql> explain select nl,lxfs from tb_user order by nl desc,lxfs desc;

根据执行计划的输出,我们可以看到也是走的Using index,但是还多了个一个Backward index scan,这个代表使用了反向扫描索引,因为我们使用的降序排序,默认是升序排序,叶子节点从小到大排序,所以就会反向扫描整个索引结构。

image-20220603142613663

3.4.排序时调整联合索引中字段的位置顺序

我们在排序时,调整一下排序字段的位置顺序,在创建联合索引时,nl字段在最左侧,lxfs字段在右侧。

在3.2.中排序时nl字段在左侧,lxfs字段在右侧,观察会有什么样的排序方式。

mysql> explain select nl,lxfs from tb_user order by lxfs,nl;

观察执行计划的输出,我们可以看到既出现了Using index又出现了Using filesort,原因就是调整了索引字段的位置,nl字段是最左前缀,我们将lxfs放在最前面,相当于违背了最左前缀法则,就会出现Using filesort。

image-20220603143310188

3.5.排序时一个字段使用升序一个字段使用降序

排序时一个字段采用升序排序,一个字段使用降序排序,观察效果。

mysql> explain select nl,lxfs from tb_user order by nl asc,lxfs desc;

观察执行计划的输出,我们可以看到既出现了Using index又出现了Using filesort,那么为什么会出现这样的现象呢?原因就是nl字段使用升序排序没问题,只需要在索引结构中顺序拿到结果,但是lxfs字段是降序排序,只能拿着结果去排序缓冲区中再进行降序排序,最终拿到结果。

image-20220603144406234

3.6.解决两个字段不同排序规则出现Using filesort

针对3.5中排序后的现象,两个字段不同的排序规则,索引默认是升序排序,nl字段的升序排序没有任何效率问题,但是lxfs字段当下拿到的是nl字段升序后的结果集,还想要对lxfs字段降序排序,只能拿到排序缓冲区中进行额外的排序,因为在nl字段升序后的结果集里,lxfs字段也是升序的,但是我们要的是降序的效果,所以只能额外排序了。

想要解决这个问题其实非常简单,只要能够实现一个索引结构里不同字段有不同的排序方式就行了,例如nl字段在索引结构里走升序排序,lxfs字段在索引结构里走降序就可以完美解决了。

不同字段的排序方式可以在创建索引时指定即可。

mysql> create index idx_user_nl_lxfs_ad on tb_user (nl asc,lxfs desc);

Column_name一列是该索引字段的排序规则,A表示asc升序排序,D表示desc降序排序。

image-20220603150220213

创建完索引后,我们再执行相同的SQL,观察执行计划。

mysql> explain select nl,lxfs from tb_user order by nl asc,lxfs desc;

观察执行计划,此时已经是Using index了。

image-20220603150343463

4.ORDER BY多字段多排序方式的索引结构图

为不同的字段设置了不同的排序规则后,在索引的叶子节点里就已经排序好了,上面图的所有字段排序规则都是升序,下面图中lxfs字段是降序,可以看到每个索引元素中手机号都是降序排序了。

image-20220603151321373

相关文章:

第48讲:SQL优化之ORDER BY排序查询的优化

文章目录1.ORDEY BY排序查询优化方面的概念2.ORDER BY排序的优化原则3.ORDER BY排序优化的案例3.1.准备排序优化的表以及索引3.2.同时对nl和lxfs字段使用升序排序3.3.同时对nl和lxfs字段使用降序排序3.4.排序时调整联合索引中字段的位置顺序3.5.排序时一个字段使用升序一个字段…...

[Datawhale][CS224W]图机器学习(三)

目录一、简介与准备二、教程2.1 下载安装2.2 创建图2.2.1 常用图创建(自定义图创建)1.创建图对象2.添加图节点3.创建连接2.2.2 经典图结构1.全连接无向图2.全连接有向图3.环状图4.梯状图5.线性串珠图6.星状图7.轮辐图8.二项树2.2.3 栅格图1.二维矩形栅格…...

2023版最新最强大数据面试宝典

此套面试题来自于各大厂的真实面试题及常问的知识点,如果能理解吃透这些问题,你的大数据能力将会大大提升,进入大厂指日可待!目前已经更新到第4版,广受好评!复习大数据面试题,看这一套就够了&am…...

CSS 中的 BFC 是什么,有什么作用?

BFC,即“块级格式化上下文”(Block Formatting Context),是 CSS 中一个重要的概念,它指的是一个独立的渲染区域,让块级盒子在布局时遵循一些特定的规则。BFC 的存在使得我们可以更好地控制文档流&#xff0…...

总结在使用 Git 踩过的坑

问题一: 原因 git 有两种拉代码的方式,一个是 HTTP,另一个是 ssh。git 的 HTTP 底层是通过 curl 的。HTTP 底层基于 TCP,而 TCP 协议的实现是有缓冲区的。 所以这个报错大致意思就是说,连接已经关闭,但是此时有未处理…...

从 HTTP 到 gRPC:APISIX 中 etcd 操作的迁移之路

罗泽轩,API7.ai 技术专家/技术工程师,Apache APISIX PMC 成员。 原文链接 Apache APISIX 现有基于 HTTP 的 etcd 操作的局限性 etcd 在 2.x 版本的时候,对外暴露的是 HTTP 1 (以下简称 HTTP)的接口。etcd 升级到 3.x…...

【C语言每日一题】——倒置字符串

【C语言每日一题】——倒置字符串😎前言🙌倒置字符串🙌总结撒花💞😎博客昵称:博客小梦 😊最喜欢的座右铭:全神贯注的上吧!!! 😊作者简…...

Native扩展开发的一般流程(类似开发一个插件)

文章目录大致开发流程1、编写对应的java类服务2、将jar包放到对应位置3、配置文件中进行服务配置4、在代码中调用5、如何查看服务调用成功大致开发流程 1、编写服务,打包为jar包2、将jar包放到指定的位置3、在配置文件中进行配置,调用对应的服务 1、编…...

【新解法】华为OD机试 - 任务调度 | 备考思路,刷题要点,答疑,od Base 提供

华为 OD 清单查看地址:blog.csdn.net/hihell/category_12199275.html 任务调度 题目 现有一个 CPU 和一些任务需要处理,已提前获知每个任务的任务 ID、优先级、所需执行时间和到达时间。 CPU 同时只能运行一个任务,请编写一个任务调度程序,采用“可抢占优先权调度”调度…...

Spring3定时任务

简介 Spring 内部有一个 task 是 Spring 自带的一个设定时间自动任务调度,提供了两种方式进行配置,一种是注解的方式,而另外一种就是 XML 配置方式了;注解方式比较简洁,XML 配置方式相对而言有些繁琐,但是应用场景的不…...

数据库版本管理工具Flyway应用研究

目录1 为什么使用数据库版本控制2 数据库版本管理工具选型:Flyway、Liquibase、Bytebase、阿里 DMSFlywayLiquibaseBytebase阿里 DMS3 Flyway数据库版本管理研究3.1 参考资料3.2 Flyway概述3.3 Flyway原理3.4 Flyway版本和功能3.5 Flyway概念3.5.1 版本迁移&#xf…...

更换 Ubuntu 系统 apt 命令安装软件源

更换 Ubuntu 系统 apt 命令安装软件源清华大学开源软件镜像站 https://mirrors.tuna.tsinghua.edu.cn/ 1. Ubuntu 的软件源配置文件 /etc/apt/sources.list MIRRORS -> 使用帮助 -> ubuntu https://mirrors.tuna.tsinghua.edu.cn/help/ubuntu/ Ubuntu 系统 apt 命令安…...

2023年可见光通信(LiFi)研究新进展

可见光无线通信Light Fidelity(LiFi)又称“光保真技术”,是一种利用可见光进行数据传输的全新无线传输技术。LiFi是一种以半导体光源作为信号发射源,利用无需授权的自由光谱实现无线连接的新型无线通信技术,支持高密度…...

Greenplum的两阶段提交

注:本文章引自终于把分布式事务讲明白了! 在前面的文章中,我们了解了单机库中的事务一致性实现以及分布式事务中的两阶段提交协议。大多数分布式系统都是采用了两阶段提交塄来保证事务的原子性,Greenplum也是采用了两阶段提交&am…...

多元回归分析 | CNN-BiLSTM卷积双向长短期记忆神经网络多输入单输出预测(Matlab完整程序)

多元回归分析 | CNN-BiLSTM卷积双向长短期记忆神经网络多输入单输出预测(Matlab完整程序) 目录 多元回归分析 | CNN-BiLSTM卷积双向长短期记忆神经网络多输入单输出预测(Matlab完整程序)预测结果评价指标基本介绍程序设计参考资料预测结果 评价指标 训练结束: 已完成最大轮…...

git命令行推送本地分支到远程仓库

之前说过Git与IDEA强强联合(HTTPS协议连接)那么如何使用命令行来推送代码呢? 如下图所示为一个基于layui的前端代码: 目录工作区文件: 本地内容就是将这些内容推送到远程仓库 首先使用git命令初始化git本地仓库&…...

在vscode中使用Typescript并运行

首先呢,我们在学习ts之前,需要先安装ts 1、安装 typescript npm install -g typescript //检查是否安装tsc -v ​ 2、生成配置文件,cd进入该文件夹,在控制台输 tsc --init ​ 此时我们就可以看到在ts文件夹下面出现了 一个tsco…...

【C++提高编程】C++全栈体系(十九)

C提高编程 第三章 STL - 常用容器 一、string容器 1. string基本概念 本质: string是C风格的字符串,而string本质上是一个类 string和char * 区别: char * 是一个指针string是一个类,类内部封装了char*,管理这个…...

Java版电能表协议解析源码(DL/T645-2007)、Modbus串口虚拟工具、网络串口调试工具分享

什么是Modbus通信协议Modbus串口调试工具Java版协议解析源码 网络与串口二合一调试助手TCPCOM: https://download.csdn.net/download/liuyuan_java/87454762 Modbus调试工具,模拟串口调试工具 https://download.csdn.net/download/liuyuan_java/874274…...

2023美赛选题建议 美国大学生数学建模竞赛ABCDEF题

选题建议和粗略思路已更新完毕 对于没有基础的同学来说CD两题上手难度较高,大家可以根据自己的实际情况选择最适合自己的题目,团队将持续更新各题后续内容,Q群322297051 A题主要难度就是建立第一问的模型,综合来看难度不大&…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...

React Native 导航系统实战(React Navigation)

导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...