SQL优化 - 排序

文章目录

  • 排序和索引
    • 降序索引
  • Filesort
  • ORDER BY 顺序问题
  • ORDER BY + LIMIT


排序和索引

如果ORDER BY操作使用了索引,那么就可以避免排序操作,因为索引本身就是按索引 key 排好序的。那什么情况下,ORDER BY会走索引呢?

例如:sakila.rental 表有一个联合索引rental_date(rental_date, inventory_id, customer_id)

在这里插入图片描述
下面来看SELECT * FROM rental ORDER BY rental_date, inventory_id;这条 sql 是否走索引

mysql> EXPLAIN SELECT * FROM rental ORDER BY rental_date, inventory_id;
+----+-------------+--------+------------+------+---------------+------+---------+------+-------+----------+----------------+
| id | select_type | table  | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra          |
+----+-------------+--------+------------+------+---------------+------+---------+------+-------+----------+----------------+
|  1 | SIMPLE      | rental | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 16008 |   100.00 | Using filesort |
+----+-------------+--------+------------+------+---------------+------+---------+------+-------+----------+----------------+
1 row in set, 1 warning (0.00 sec)

从执行计划来看是没走索引的,因为使用了SELECT *。在这种情况下,扫描整个索引并查找表行以查找不在索引中的列可能比扫描表并对结果进行排序成本更高,因此优化器可能不会使用索引。如果SELECT *仅选择索引列,也就是使用索引覆盖策略,则可以使用索引来避免排序。例如:

EXPLAIN SELECT inventory_id, rental_date, customer_id 
FROM rental ORDER BY rental_date, inventory_id;

那是不是SELECT *都不走索引?

如果索引不完全包含查询的所有列,需要回表的话,则需要WHERE子句的选择性足以使索引范围扫描比表扫描成本更低,则优化器会选择使用索引。也就是让索引的所有未使用部分和所有额外的ORDER BY列都是WHERE子句中的常量条件。这样即使ORDER BY的列与索引不完全匹配,也可以使用索引。例如:

SELECT * FROM t1 WHERE key_part1 = constantORDER BY key_part2;

降序索引

https://dev.mysql.com/doc/refman/8.0/en/descending-indexes.html
如果索引的排序和ORDER BY的排序不一致,可以考虑使用降序索引

Filesort

如果ORDER BY不满足用索引的条件,MySQL将执行文件排序操作,读取表的行并对其进行排序。

从MySQL 8.0.12开始,优化器会根据需要增量地分配内存缓冲区(叫做 Sort Buffer),直到超过sort_buffer_size的大小,而MySQL 8.0.12之前,是直接预先分配固定数量的sort_buffer-size字节大小的内存缓冲区。将sort_buffer_size设置为更大的值来加速更大的排序。增量分配的这种方式可以在小排序发生时不会占用过多的内存。

如果结果集太大(超过sort_buffer_size)而无法放入内存,文件排序操作会根据需要使用临时磁盘文件,这种情况性能就比较差了

mysql> EXPLAIN SELECT * FROM rental ORDER BY inventory_id;
+----+-------------+--------+------------+------+---------------+------+---------+------+-------+----------+----------------+
| id | select_type | table  | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra          |
+----+-------------+--------+------------+------+---------------+------+---------+------+-------+----------+----------------+
|  1 | SIMPLE      | rental | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 16008 |   100.00 | Using filesort |
+----+-------------+--------+------------+------+---------------+------+---------+------+-------+----------+----------------+
1 row in set, 1 warning (0.00 sec)

ORDER BY 顺序问题

如果order by列有相同的值,那么MySQL可以自由地以任何顺序返回这些行。换言之,只要order by列的值不重复,就可以保证返回的顺序。可以在order by子句中包含附加列,以使顺序具有确定性。为了保证每次都返回的顺序一致可以额外增加一个排序字段(比如:id),用两个字段来尽可能减少重复的概率

MySQL具体的排序策略受以下几个因素影响:

  1. 是否可用的索引
  2. 预期结果大小
  3. MySQL版本

一般来说,排序处理过程如下

  1. 读取与WHERE子句匹配的行
  2. 对于每一行,记录一个由排序 key 和行位置组成的值元组,以及查询所需的列
  3. 按排序 key 的值对元组进行排序
  4. 按排序好的顺序根据行未知检索行,但直接从排序的元组中读取所需的列,而不是第二次访问表

ORDER BY + LIMIT

对于order by查询,带或者不带limit可能返回行的顺序是不一样的。

如果limit row_count 与 order by 一起使用,那么在找到第一个row_count就停止排序,直接返回。

例如平时开发常见的分页查询

SELECT * FROM rental ORDER BY inventory_id LIMIT 1, 10

会导致多页出现同一条数据
在这里插入图片描述
如果想在limit存在或不存在的情况下,都保证排序结果相同,可以额外加一个排序条件。例如id字段是唯一的,可以考虑在排序字段中额外加个id排序去确保顺序稳定。这样分页的问题就解决了。

SELECT * FROM rental ORDER BY rental_id, inventory_id LIMIT 1, 10

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

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

相关文章

C#基于SkiaSharp实现印章管理(10)

向PDF文件插入印章图片比之前实现的向图片文件插入印章麻烦得多。   最初的想法是使用PDF浏览控件在线打开PDF文件,然后在控件中实现鼠标移动时动态显示印章,点击鼠标时向当前PDF页面的鼠标点击位置插入图片。由于是.net 8的Winform项目,选…

Elasticsearch学习记录

阅读前须知 本文通过安装elasticsearch-7.17.0为基础,使用 kibana-7.17.0 对 elasticsearch 进行操作,本文中 es 是对 elasticsearch 的简写。 下载地址:elasticsearch_免费高速下载|百度网盘-分享无限制 (baidu.com) 1 初识Elasticsearch …

用 LoRA 微调 Stable Diffusion:拆开炼丹炉,动手实现你的第一次 AI 绘画

总得拆开炼丹炉看看是什么样的。这篇文章将带你从代码层面一步步实现 AI 文本生成图像(Text-to-Image)中的 LoRA 微调过程,你将: 了解 Trigger Words(触发词)到底是什么,以及它们如何影响生成结…

【大数据】深入解析分布式数据库:架构、技术与未来

目录 1. 分布式数据库的定义2. 架构类型2.1 主从架构2.2 同步与异步复制2.3 分片架构 3. 技术实现3.1 一致性模型3.2 CAP理论3.3 数据存储引擎 4. 应用场景5. 选择分布式数据库的因素5.1 数据一致性需求5.2 读写负载5.3 成本5.4 技术栈兼容性 6. 未来发展趋势总结 分布式数据库…

spring boot jar 分离自动部署脚本

背景 远程部署时spring boot 包&#xff0c;比较大。可以采用依赖库和业务包分离的方式。提供一个脚本进行自动部署 maven 配置分离jar包 <build><finalName>${project.artifactId}</finalName><plugins><plugin><groupId>org.springfra…

springboot cache

springboot cache 简要介绍 Spring 对缓存提供支持&#xff0c;核心思路是对方法的参数和返回值的缓存&#xff0c;当开发者调用一个方法时&#xff0c;将方法的参数和返回值作为key/value缓存起来&#xff0c;当再次调用该方法时&#xff0c;如果缓存中有数据&#xff0c;就直…

redis面试-2024

1、Redis的基本数据结构类型 string、list、set、hash、zet。还有三种特殊类型&#xff1a;Geospatial、Hyperloglog、bitMap。 2、各数据类型对应的场景 3、redis快的原因 *基于内存 内存读写效率远高于磁盘读写&#xff0c;省去磁盘IO操作 *存储形式 Redis作为K-V键值对…

SpringCloud学习记录|day2

学习材料 2024最新SpringCloud微服务开发与实战&#xff0c;java黑马商城项目微服务实战开发&#xff08;涵盖MybatisPlus、Docker、MQ、ES、Redis高级等&#xff09; Docker 部署工具。原来为了学习RabbitMQ安装过了。 但是忘记差不多了。 发现要回到root用户才能启动docke…

MFC有三个选项:MFC ActiveX控件、MFC应用程序、MFC DLL,如何选择?

深耕AI&#xff1a;互联网行业 算法研发工程师 ​ 目录 MFC ActiveX 控件 控件的类型 标准控件 自定义控件 ActiveX控件 MFC ActiveX控件 标准/自定义控件 MFC ActiveX控件分类 3种MFC如何选择&#xff1f; MFC ActiveX控件 MFC 应用程序 MFC DLL 总结 举例说明…

微信小程序处理交易投诉管理,支持多小程序

大家好&#xff0c;我是小悟 1、问题背景 玩过微信小程序生态的&#xff0c;或许就有这种感受&#xff0c;如果收到投诉单&#xff0c;不会及时通知到手机端&#xff0c;而是每天早上10:00向小程序的管理员及运营者推送通知。通知内容为截至前一天24时该小程序账号内待处理的交…

k8s基础环境部署

什么是k8s K8s&#xff0c;全称Kubernetes&#xff0c;是一个开源的容器编排平台&#xff0c;由谷歌&#xff08;Google&#xff09;开发并开源。Kubernetes这个名字源于希腊语&#xff0c;意为“舵手”或“飞行员”&#xff0c;而“k8s”这个缩写则是因为“k”和“s”之间有八…

vue中如何实现组件通信

1. 父子组件通信 1. props和emits 我们最常见的组件通信就是父子组件数据通信。父子组件实现数据通信需要使用props和emit两个api。 在父组件中我们通过props将数据绑定给子组件&#xff0c;在子组件中我们可以通过props对象来收集到父组件传递的数据。 在子组件想要修改的pr…

【目标检测】yolo的三种数据集格式

目标检测中数据集格式之间的相互转换--coco、voc、yolohttps://zhuanlan.zhihu.com/p/461488682?utm_mediumsocial&utm_psn1825483604463071232&utm_sourcewechat_session【目标检测】yolo的三种数据集格式https://zhuanlan.zhihu.com/p/525950939?utm_mediumsocial&…

【Unity】本地化实现

个人向笔记。 1 前言 记录一下自己的本地化实现思路&#xff0c;暂时只讲本文的本地化实现。 2 文本本地化方案-个人 本地化实现是基于Luban的。自己使用Luban实现了一个“配置表模块”&#xff0c;又实现了一个“全局配置模块”&#xff0c;之后再基于这两个模块实现了“文本…

【移植】一种快速移植OpenHarmony Linux内核的方法

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ 持续更新中…… 移植概述 本文面向希望将 OpenHarmony 移植到三方芯片平台硬件的开…

基于Spring Boot+Vue的减肥健康管理系统设计和实现【原创】(BMI算法,协同过滤算法、图形化分析)

&#x1f388;系统亮点&#xff1a;图形化分析、BMI算法&#xff0c;协同过滤算法&#xff1b; 一.系统开发工具与环境搭建 1.系统设计开发工具 后端使用Java编程语言的Spring boot框架 项目架构&#xff1a;B/S架构 运行环境&#xff1a;win10/win11、jdk17 前端&#xff1a…

计算机网络-系分(5)

目录 计算机网络 DNS解析 DHCP动态主机配置协议 网络规划与设计 层次化网络设计 网络冗余设计 综合布线系统 1. 双栈技术 2. 隧道技术 3. 协议转换技术 其他网络技术 DAS&#xff08;Direct Attached Storage&#xff0c;直连存储&#xff09; NAS&#xff08;Net…

Oracle RAC中停止has、crs、cluster的区别

1.首先介绍一下这3个服务 Has&#xff1a;是高可用服务&#xff0c;用在restart环境&#xff0c;可以是单机环境也可以是RAC环境&#xff0c;不管单机环境还是RAC环境&#xff0c;都可以执行crsctl check has&#xff0c;在RAC环境下&#xff0c;可以简单理解成cluster的一部分…

【Immich部署与访问】自托管媒体文件备份服务 Immich 本地化部署与远程访问存储数据

文章目录 前言1.关于Immich2.安装Docker3.本地部署Immich4.Immich体验5.安装cpolar内网穿透6.创建远程链接公网地址7.使用固定公网地址远程访问 前言 本篇文章介绍如何在本地搭建lmmich图片管理软件&#xff0c;并结合cpolar内网穿透实现公网远程访问到局域网内的lmmich&#…

【环境配置】科研小白Windows下安装Git

2024年小白使用Win10安装Git 2.46.2教程&#xff1a; 1 下载安装包 访问下载地址 Git - Downloading Package (git-scm.com) 下载之后打开文件 2 安装过程 点击Next 2.1 选择安装路径 2.2 选择勾选必要组件 2.3 一路Next 这一步直接Next即可 继续点击Next 继续点击Ne…