MySQL 查询 limit 100000000, 10 和 limit 10 速度一样快吗?

MySQL 查询 limit 100000000, 10 和 limit 10 速度一样快吗?

在这里插入图片描述

MySQL内部分为server层存储引擎层。一般情况下存储引擎都用innodb。

server层有很多模块,其中需要关注的是执行器是用于跟存储引擎打交道的组件。

执行器可以通过调用存储引擎提供的接口,将一行行数据取出,当这些数据完全符合要求(比如满足其他where条件),则会放到结果集中,最后返回给调用mysql的客户端

两种查询方式。对应 limit offset, size 和 limit size 两种方式。

而其实 limit size ,相当于 limit 0, size。也就是从0开始取size条数据。

也就是说,两种方式的区别在于offset是否为0。

1. 以主键索引的 LIMIT 10 为例

LIMIT 10 查询的是结果集的前 10 行数据。这种情况下,MySQL 只需要扫描并返回前 10 行数据,操作相对简单且快速。

SELECT * FROM table_name LIMIT 10;

server层会调用innodb的接口,在innodb里的主键索引中获取到第0到10条完整行数据,依次返回给server层,并放到server层的结果集中,返回给客户端。

2. 以主键索引的 LIMIT 100000000, 10 为例

LIMIT 100000000, 10 查询的是从结果集的第 100000001 行开始的 10 行数据。这种情况下,MySQL 需要先扫描前 100000000 行数据并丢弃,然后再返回接下来的 10 行数据。这种操作会导致大量的行扫描和丢弃操作,效率很低。

SELECT * FROM table_name LIMIT 100000000, 10;

server层会调用innodb的接口,由于这次的offset=100000000,会在innodb里的主键索引中获取到第0到(100000000+ 10)条完整行数据,返回给server层之后根据offset的值挨个抛弃,最后只留下最后面的size条,也就是10条数据,放到server层的结果集中,返回给客户端。

可以看出,当offset非0时,server层会从引擎层获取到很多无用的数据,而获取的这些无用数据都是要耗时的。

以非主键索引的 LIMIT 10 为例

SELECT * FROM table_name LIMIT 10;

server层会调用innodb的接口,在innodb里的非主键索引中获取到第0条数据对应的主键id后,回表到主键索引中找到对应的完整行数据,然后返回给server层,server层将其放到结果集中,返回给客户端。

而当offset>0时,且offset的值较小时,逻辑也类似,区别在于,offset>0时会丢弃前面的offset条数据。

也就是说非主键索引的limit过程,比主键索引的limit过程,多了个回表的消耗。

但当offset变得非常大时,比如600万,此时执行explain。

可以看到type那一栏显示的是ALL,也就是全表扫描

这是因为server层的优化器,会在执行器执行sql语句前,判断下哪种执行计划的代价更小。

很明显,优化器在看到非主键索引的600w次回表之后,摇了摇头,还不如全表一条条记录去判断算了,于是选择了全表扫描。

因此,当limit offset过大时,非主键索引查询非常容易变成全表扫描。是真性能杀手

性能比较

  • LIMIT 10:MySQL 只需扫描前 10 行数据,快速返回结果,性能高。
  • LIMIT 100000000, 10:MySQL 需要扫描前 100000000 行数据并丢弃,然后返回接下来的 10 行数据,性能低。

优化大偏移量的查询

当你需要从一个大偏移量开始查询时,可以采用以下优化方法:

1. 使用覆盖索引

确保查询使用了覆盖索引,这样可以减少全表扫描的开销。

SELECT col1, col2 FROM table_name FORCE INDEX (index_name) WHERE indexed_column >= value LIMIT 100000000, 10;
2. 通过主键范围查询

使用主键范围查询,先查找主键值,再根据主键值进行查询,避免大偏移量的扫描。

第一步:找到起始主键值
SELECT id FROM table_name ORDER BY id LIMIT 100000000, 1;-- 假设起始主键值为 start_id
-- 第二步:基于主键值进行查询
SELECT * FROM table_name WHERE id >= start_id LIMIT 10;
3. 使用延迟关联(Deferred Join)

先根据索引字段查找主键,再根据主键进行关联查询,从而避免大偏移量的扫描。

-- 第一步:查找主键值
SELECT id FROM table_name ORDER BY id LIMIT 100000000, 10;-- 第二步:基于主键进行关联查询
SELECT * FROM table_name WHERE id IN (id1, id2, ..., id10);
4. 使用分页技术

对于用户分页的场景,通常需要记录当前页和页数,采用基于主键或其他唯一标识的分页技术,避免使用 LIMIT 大偏移量查询。

结论

MySQL 中 LIMIT 100000000, 10LIMIT 10 的查询速度并不一样。大偏移量的查询会导致性能问题,可以通过覆盖索引、主键范围查询、延迟关联等方法进行优化。

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

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

相关文章

整合StarRocks更新表全部知识点

总结StarRocks更新表的全部内容的集合(V3.2版本) 一、基本功能 聚合函数replace的聚合表主键被主键表替代采用Merge-On-Read的策略,读取时需要在线Merge多个版本的数据文件,谓词和索引无法下推至底层数据,会严重影响…

LeetCode:对称的二叉树(C语言)

1、问题概述:给一个二叉树,看是否按轴对称 2、示例 示例 1: 输入:root [1,2,2,3,4,4,3] 输出:true 示例 2: 输入:root [1,2,2,null,3,null,3] 输出:false 3、分析 (1&a…

解决 Android 应用安装错误:INSTALL_FAILED_BAD_PERMISSION_GROUP

解决 Android 应用安装错误:INSTALL_FAILED_BAD_PERMISSION_GROUP 在开发 Android 应用时,我们有时会遇到安装错误。这篇文章将讨论一种常见的错误:INSTALL_FAILED_BAD_PERMISSION_GROUP,并介绍解决方法。 问题描述 在尝试安装…

Go实用技巧

Golang实用技巧 Golang实用技巧 Context 1. 为了gorouines更可靠,避免实用context.Background()2. 不幸得是,context.Value 不是我们的朋友3. 使用context.WithoutCancel 保持 context 活跃 Context 1. 为了gorouines更可靠,避免实用con…

教学用MQTT工具的思考

前言 我在《智能物联网应用设计》课程中有个实验就是学习MQTT的使用,目前使用的是以下几个工具: 客户端使用MQTTX本地服务器使用的是mosquitto 云端服务器采用的巴法云协议分析软件采用的是Wireshark 这里Wireshark基本没有啥可以替代的,而…

Vue3 study

Vue3 工程 创建 还是能像 vue2 一样通过 vue-cli 创建,即 vue create projectName 但是官方更推荐 vite 创建,即 npm create vuelatest,然后从项目名开始配置 总结:入口在 index.html,它会引入 main.ts,…

Win11 操作(四)g502鼠标连接电脑不亮灯无反应

罗技鼠标连接电脑不亮灯无反应 前言 罗技技术💩中💩,贴吧技术神中神! 最近买了一个g502,结果买回来直接插上电脑连灯都不亮,问了一下客服。客服简单的让我换接口,又是下载ghub之类的&#xf…

Go 1.22 remote error: tls: handshake failure

Golang 1.22 remote error: tls: handshake failure 1.22之前运行下面代码是没有错误 package mainimport ("crypto/tls""fmt""net/http" )func main() {http.DefaultTransport.(*http.Transport).TLSClientConfig &tls.Config{InsecureS…

从零开始!JupyterNotebook的安装教程

安装 Anaconda 1、下载 Anaconda: 访问 Anaconda 官方网站 (https://www.anaconda.com/products/distribution/) 下载适合您操作系统的 Anaconda 发行版。 2、安装 Anaconda: Windows:运行下载的安装程序,选择“Just Me”…

Leetcode—297. 二叉树的序列化与反序列化【困难】

2024每日刷题(148) Leetcode—297. 二叉树的序列化与反序列化 实现代码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(…

Esxi 上的 CentOS 7.6 系统中搭建本地 Yum 源

1. 挂载 CentOS 安装盘 在 ESXi 管理界面中,将 CentOS 安装 ISO 文件挂载到虚拟机。 2. 挂载光盘镜像 在虚拟机中执行以下命令,将安装盘挂载到 /mnt/cdrom: mkdir /mnt/cdrom mount /dev/cdrom /mnt/cdrom3. 禁用所有默认的 YUM 源 进入…

4. kubernetes资源——deployment无状态负载

kubernetes资源——deployment无状态负载 一、deployment无状态负载1、deployment无状态负载 二、创建deployment1、创建deployment2、验证副本维护 三、deployment滚动更新1、创建pod2、测试滚动更新流程2.1、修改镜像版本、或者副本数2.2、执行更新2.3、查看更新过程2.4、查看…

低代码+工作流:拔高企业效率的数字化神器

前言 传统的软件开发过程中,随着产品业务的不断更新迭代,会产生大量的重复性的工作。这些重复性的工作其实是遵循着某种特定的规则,假如在开发阶段我们没有做好很好的抽象,在后期做新业务新产品时,我们仍然要花费大量…

AutoMySQLBackup execution.. Backup failed Docker部署mysql 自动备份失败!!

摘要: Docker容器部署的mysql5.7版本遇到使用AutoMYSQLBackup备份失败了,反复修改automysqlbackup.conf也不起效。这里推荐一种新的办法绕开老路子直接备份。 目录 一、环境介绍 二、AutoMYSQLBackup 三、问题描述 四、解决思路 4.1第一种解决思…

Java黑色界面陪玩高端小程序源码陪练APP源码H5公众号源码电竞系统

🚀【电竞新纪元】解锁高端陪玩小程序源码 & 陪练APP秘籍,H5公众号全攻略! 🎮 开篇:电竞热潮下的新机遇 Hey游戏迷们!随着电竞行业的蓬勃发展,你是否也想在这股浪潮中分得一杯羹&#xff1…

学习笔记9:雪花算法

雪花算法 雪花算法(Snowflake Algorithm)是一种生成唯一ID的算法,最初由Twitter开发。它的主要特点是生成的ID是64位的长整型数字,具有以下特性: 唯一性:每个生成的ID都是唯一的。趋势递增:生…

Python爬虫小项目实战

1.自动获取小说多个章节内容 2.获取英雄联盟里面的全部英雄 3. 简单地自动抽奖系统 4. 简单地点赞系统 5. 制作查询手机号工具 6. 制做登录系统 7. 操作excel办公自动化 8. 自动批量保存图片 9. 获取NBA数据 10. 获取彩票信息 11. 获取房地产信息 12. 获取小说…

opencascade AIS_Manipulator源码学习

前言 AIS_Manipulator 是 OpenCASCADE 库中的一个类,用于在3D空间中对其他交互对象或一组对象进行局部变换。该类提供了直观的操控方式,使用户可以通过鼠标进行平移、缩放和旋转等操作。 详细功能 交互对象类,通过鼠标操控另一个交互对象…

git 操作汇总【迭代更新中】

文章目录 0x1初始化操作0x11 生成公钥0x12 配置账号和邮箱 0x20x21 拉取代码0x22 推送代码0x23 设置远端分支 0x30x31 提交mr 0x40x41 子模块0x42 子模块添加 0x1初始化操作 0x11 生成公钥 ssh-keygen0x12 配置账号和邮箱 git config --global user.name username git confi…

瀚高数据库初级考试认证

pg_dumpall可以转储全局角色和表空间信息 单选题2分 A. 是 B. 否 回答正确(2分) 答案: A 解析:pg_dumpall备份一个给定集簇中的每一个数据库,并且也保留了集簇范围的数据,如角色和表空间定义。 2. 自定义文件格式必须与pg_restore…