我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Mysql优化技巧之Limit查询的示例分析

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Mysql优化技巧之Limit查询的示例分析

小编给大家分享一下Mysql优化技巧之Limit查询的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!

前言

在实际业务中对于分页来说是一个比较常见的业务需求。那么就会使用到limit查询,当我们在使用Limit查询的时候,在数据比较小、或者只查询前面一部分数据的时候效率是很高的。但是当数据量大的时候,或者查询offset数量比较大的时候,如:limit 100000,20效率往往就不尽人意了。通常的一个办法就是Limit配合order by,如果order by有对用户的索引的话,效率通常是比较不错的。

对于这种情况,最简单的查询就是 使用覆盖索引,查询某些需要的列。这样的效果是很好的

如下面这个

mysql> SELECT * FROM student LIMIT 1000000,1;
+---------+------------+------------+------------+-------+---------------------+
| id  | first_name | last_name | created_at | score | updated_at   |
+---------+------------+------------+------------+-------+---------------------+
| 1000001 | kF9DxBgnUi | yLXnPSHJpH | 2019-07-11 | 97 | 2019-07-11 14:29:59 | |
+---------+------------+------------+------------+-------+---------------------+
1 rows in set (0.31 sec)

可以看到时间

mysql> EXPLAIN SELECT score,first_name FROM student ORDER BY created_at LIMIT 1000000,20 \G
*************************** 1. row ***************************
   id: 1
 select_type: SIMPLE
  table: student
 partitions: NULL
   type: index
possible_keys: NULL
   key: time_sorce_name
  key_len: 69
   ref: NULL
   rows: 1000001
  filtered: 100.00
  Extra: Using index
1 row in set, 1 warning (0.00 sec)

mysql>

这样的话查询的列使用到的了覆盖索引,扫描行数会减少很多,但是这样的效果也不是很尽人意,但是如果有其他的查询的话,这样的查询也会变的很慢。

比如我们加上last_name列。

如下

mysql> SELECT score,first_name,last_name FROM student ORDER BY created_at LIMIT 1000000,1;
+-------+------------+------------+
| score | first_name | last_name |
+-------+------------+------------+
| 86 | knKsV2g2fY | WB5qJeLZuk |
+-------+------------+------------+
1 row in set (4.81 sec)

mysql>

这个查询需要执行 4秒多的时间。通过分析可以看到这个查询是没有办法使用索引的

mysql> explain SELECT score,first_name,last_name FROM student ORDER BY created_at LIMIT 1000000,1\G
*************************** 1. row ***************************
   id: 1
 select_type: SIMPLE
  table: student
 partitions: NULL
   type: ALL
possible_keys: NULL
   key: NULL
  key_len: NULL
   ref: NULL
   rows: 6489221
  filtered: 100.00
  Extra: Using filesort
1 row in set, 1 warning (0.00 sec)

mysql>

那么我们现在把查询修改如下

mysql> SELECT student.score,student.first_name FROM student INNER JOIN (SELECT id FROM student ORDER BY created_at LIMIT 1000000,1 ) AS temp USING(id);
+-------+------------+
| score | first_name |
+-------+------------+
| 15 | 2QWZ  |
+-------+------------+
1 row in set (0.18 sec)
mysql> EXPLAIN SELECT student.score,student.first_name,last_name FROM student INNER JOIN (SELECT id FROM student ORDER BY created_at LIMIT 1000000,1 ) AS temp USING(id);
+----+-------------+------------+------------+--------+---------------+-----------------+---------+---------+---------+----------+-------------+
| id | select_type | table  | partitions | type | possible_keys | key    | key_len | ref  | rows | filtered | Extra  |
+----+-------------+------------+------------+--------+---------------+-----------------+---------+---------+---------+----------+-------------+
| 1 | PRIMARY  | <derived2> | NULL  | ALL | NULL   | NULL   | NULL | NULL | 1000001 | 100.00 | NULL  |
| 1 | PRIMARY  | student | NULL  | eq_ref | PRIMARY  | PRIMARY   | 4  | temp.id |  1 | 100.00 | NULL  |
| 2 | DERIVED  | student | NULL  | index | NULL   | time_sorce_name | 69  | NULL | 1000001 | 100.00 | Using index |
+----+-------------+------------+------------+--------+---------------+-----------------+---------+---------+---------+----------+-------------+
3 rows in set, 1 warning (0.00 sec)

分析结果,可以看到这个时候只查询了1000001一条数据记录。为什么会有这样的变化呢。这种叫延时关联,先通过使用覆盖索引查询返回需要的主键,再根据主键关联原表获得需要的数据,尽可能的减少了需要扫描的行数。

在某些特定的场合,其实有另外一种优化方案的。比如要获取最新的几条插入记录。那么在上一次查询的时候我们可以记录下最后一条记录的主键ID(last_id)。
那么查询就可以改为

SELECT score,first_name,last_name,id FROM student WHERE id>=last_id ORDER BY id ASC LIMIT 1

比如last_id=1000000那么这个查询就会从1000000开始。这样的场景不管数据到多大的offset性能都会很好。

看完了这篇文章,相信你对“Mysql优化技巧之Limit查询的示例分析”有了一定的了解,如果想了解更多相关知识,欢迎关注亿速云行业资讯频道,感谢各位的阅读!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Mysql优化技巧之Limit查询的示例分析

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

下载Word文档

猜你喜欢

mysql优化之慢查询分析+explain命令分析+优化技巧总结

分析慢查询1.查看慢SQL是否启用,查看命令:show variables like log_slow_queries; 如果结果为ON则是开启了,如果为OFF则表示禁用了。2.开启慢查询命令:set global log_slow_q
2023-02-18

MySQL 分页查询的优化技巧

在有分页查询的应用中,包括 LIMIT 和 OFFSET 的查询十分常见,而且几乎每个都会有一个 ORDER BY 子句。如果使用索引排序的话将对性能优化十分有帮助,否则服务端需要做很多文件排序。一个高频的问题是 offset 的值过大。如
2022-05-20

MySQL优化之慢查询日志实例分析

本篇内容主要讲解“MySQL优化之慢查询日志实例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“MySQL优化之慢查询日志实例分析”吧!一、慢查询日志概念对于SQL和索引的优化问题,我们会使用
2023-07-02

MySQL查询性能优化的实战技巧

MySQL查询性能优化是一个复杂的过程,涉及到多个方面。以下是一些实战技巧,可以帮助你提高MySQL查询的性能:使用索引:索引是提高查询性能的关键。确保在经常用于查询的列上创建索引,并且索引应该是有意义的,即索引列应该是有序的。同时,要注意
MySQL查询性能优化的实战技巧
2024-10-21

MySQL中子查询的示例分析

这篇文章主要介绍了MySQL中子查询的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、子查询定义   定义:  子查询允许把一个查询嵌套在另一个查询当中。  子查询
2023-06-20

编程热搜

目录