SQL优化 - 排序

news2024/10/6 1:32:10

文章目录

  • 排序和索引
    • 降序索引
  • 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 = constant
  ORDER 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.coloradmin.cn/o/2190895.html

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

相关文章

专题十_穷举vs暴搜vs深搜vs回溯vs剪枝_二叉树的深度优先搜索_算法专题详细总结

目录 搜索 vs 深度优先遍历 vs 深度优先搜索 vs 宽度优先遍历 vs 宽度优先搜索 vs 暴搜 1.深度优先遍历 vs 深度优先搜索(dfs) 2.宽度优先遍历 vs 宽度优先搜索(bfs) 2.关系图暴力枚举一遍所有的情况 3.拓展搜索问题全排列 决策树 1. 计算布尔⼆叉树的值(medi…

CF2013E Prefix GCD

【题目大意】 给定一个长度为 n n n 的数列 a 1 … n a_{1 \dots n} a1…n​,你可以将 a 1 … n a_{1 \dots n} a1…n​ 按照任意顺序进行重排,使得: ∑ i 1 n gcd ⁡ { a 1 , a 2 , a 3 , … , a n } \sum\limits_{i1}^{n}\gcd\left \{…

10.5学习

1.GateWay GateWay⽬标是取代Netflflix Zuul,它基于Spring5.0SpringBoot2.0WebFlux等技术开发,提供统⼀的路由⽅式(反向代理)并且基于 Filter(定义过滤器对请求过滤,完成⼀些功能) 链的⽅式提供了⽹关基本的功能&…

探索 Python 虚拟环境的奥秘:virtualenv 的魔法世界

文章目录 探索 Python 虚拟环境的奥秘:virtualenv 的魔法世界背景:为何选择 virtualenv?虚拟环境的守护者:virtualenv 是什么?安装 virtualenv:简单几步,开启隔离之旅掌握 virtualenv 的基本用法…

Relu激活

ReLU(Rectified Linear Unit)激活函数 是卷积神经网络(CNN)以及许多深度学习模型中最常用的激活函数之一。它的主要作用是引入非线性,使模型能够学习和表达更复杂的特征。以下是对ReLU激活函数的详细解释。 1. ReLU的…

C语言进阶版第16课—自定义类型:结构体

文章目录 1. 结构体类型的声明和初始化2. 结构体自引用3. 结构体内存对齐3.1 结构体内存对齐规则3.2 修改默认对齐数 4. 结构体传参4. 结构体实现位段5. 位段使用的注意事项 1. 结构体类型的声明和初始化 结构体在使用之前都要对其类型进行声明,关键字是struct&…

15分钟学 Python 第36天 :Python 爬虫入门(二)

Python 爬虫入门:环境准备 在进行Python爬虫的学习和实践之前,首先需要准备好合适的开发环境。本节将详细介绍Python环境的安装、必要库的配置、以及常用工具的使用,为后续的爬虫编写奠定坚实的基础。 1. 环境准备概述 1.1 为什么环境准备…

mp4转gif在线转换怎么转?7个视频转动图方法不容错过!(超简单)

mp4转gif在线转换怎么转?如今,将mp4视频转换为gif动图格式,满足了人们对易于分享和网络传播内容的需求。与mp4视频相比,gif动图文件体积相对较小,几乎所有网络平台都支持这种格式,无需额外安装插件或软件。…

CSID-GAN:基于生成对抗网络的定制风格室内平面设计框架论文阅读

CSID-GAN: A Customized Style Interior Floor Plan Design Framework Based on Generative Adversarial Network 摘要前言II. CSID-GAN METHODA. Overall FrameworkB. Algorithm and Loss Function III. DATASETS AND EVALUATION METRICSA. DatasetsB. Evaluation Metrics IV.…

信息安全工程师(34)访问控制模型

前言 访问控制模型是实现访问控制的基础,不同的访问控制模型提供了不同的访问控制策略和机制,以适应不同的安全需求。 一、自主访问控制模型(DAC) 定义:指资源的所有者有权决定谁可以访问其资源以及访问的方式。资源的…

如何实现事件流操作

文章目录 1 概念介绍2 使用方法3 示例代码我们在上一章回中介绍了通道相关的内容,本章回中将介绍StreamProvider组件.闲话休提,让我们一起Talk Flutter吧。 1 概念介绍 在Flutter中Stream是经常使用的组件,对该组件的监听可void main() {///让状态栏和程序的appBar融为一体…

macos安装mongodb

文章目录 说明安装和配置安装mongodb配置PATH变量 验证日志及数据存放目录 mac启动和关闭mongodb后台启动失败问题mongodb-compass(GUI) 说明 Homebrew core 列表目前已经将 MongoDB 移除,不再为其提供支持。但是使用国内镜像的brew还是可以安装的!这里直接从官网下…

使用 Python 代码连接 PostgreSQL

Python 是一个功能非常强大的编程语言,尤其在与数据库交互时,提供了丰富的解决方案。在实际项目中,我们经常需要通过 Python 连接并操作数据库。为了简化这种操作,ORM(对象关系映射)框架提供了便利。ORM 能…

aws(学习笔记第一课) AWS CLI,创建ec2 server以及drawio进行aws画图

aws(学习笔记第一课) 使用AWS CLI 学习内容: 使用AWS CLI配置密钥对创建ec2 server使用drawio(vscode插件)进行AWS的画图 1. 使用AWS CLI 注册AWS账号 AWS是通用的云计算平台,可以提供ec2,vpc,SNS以及clo…

灵足时代:具身智能核心部件的新秀崛起——解析数千万元天使轮融资

在智能科技日新月异的今天,具身智能作为连接物理世界与数字世界的重要桥梁,正逐步成为科技创新的前沿阵地。近日,具身智能核心部件领域的新锐公司——“灵足时代”宣布完成数千万元天使轮融资,这一消息无疑为行业内外带来了强烈的震撼与期待。本轮融资由雅瑞智友科学家基金…

多用户网页聊天室(测试报告)

一、项目背景 随着现代互联网的快速发展,实时通信系统(如聊天应用)已成为人们日常交流的重要工具。多用户网页聊天室项目旨在为用户提供一个基于Web的实时聊天平台,支持用户之间的即时通信、好友管理和历史消息记录查看。为了提升…

ModuleNotFoundError: No module named ‘package‘

报错: Traceback (most recent call last): File “”, line 198, in run_module_as_main File “”, line 88, in run_code File "D:\python\helloworld.venv\Scripts\pip.exe_main.py", line 4, in File "D:\python\helloworld.venv\Lib\site-pac…

3分钟学会下载 blender

1. blender简介 Blender是一款开源的3D创作套件,它由Blender Foundation维护,并得到了全球志愿者和专业开发者的支持。Blender广泛应用于3D模型的制作、动画、渲染、视频编辑、游戏创建、模拟、 composting以及3D打印等多个领域。 功能特点&#xff1a…

Gitlab flow工作流

Gitlab flow Gitlab flow 是 Git flow 与 Github flow 的综合。它吸取了两者的优点,既有适应不同开发环境的弹性,又有单一主分支的简单和便利。它是 Gitlab.com 推荐的做法。 1 上游优先 Gitlab flow 的最大原则叫做"上游优先"(…

【网络篇】计算机网络——应用层详述(笔记)

目录 一、应用层协议原理 1. 进入应用层 2. 网络应用程序体系结构 (1)客户-服务器体系结构(client-server architecture) (2) P2P 体系结构(P2P architecture) 3. 进程间通讯 …