博客
关于我
4种MySQL分页查询优化的方法,你知道几个?
阅读量:377 次
发布时间:2019-03-05

本文共 2057 字,大约阅读时间需要 6 分钟。

数据库分页查询优化实践指南

当需要从数据库查询的表有上万条记录时,一次性查询所有结果会变得非常缓慢,特别是在数据量持续增加的情况下,这时分页查询就显得尤为重要。数据库分页查询方法多种多样,每种方法都有其适用的场景和优化点。本文将简要介绍几种常见的分页查询优化方法,并通过实际测试结果进行对比分析。

准备工作

为了对下面的优化方法进行测试,我们基于现有表进行说明:

  • 表名:order_history
  • 描述:某个业务的订单历史表
  • 主要字段:unsigned int id,tinyint(4) int type
  • 字段情况:该表共有37个字段,不包含text等大型数据,最大为varchar(500),id字段为索引且递增。
  • 数据量:5709294
  • MySQL版本:5.7.16

如果需要自己测试,可以编写shell脚本等工具插入数据进行测试。

一般分页查询

一般的分页查询可以通过MySQL的LIMIT子句实现。LIMIT子句用于指定返回的记录数。需要注意以下几点:

  • 参数说明

    • 第一个参数指定第一个返回记录行的偏移量(默认为0)。
    • 第二个参数指定返回记录行的最大数目。
    • 如果只给定一个参数,则表示返回最多的记录行数目。
    • 第二个参数为-1时,表示检索从某个偏移量到记录集结束的所有记录。
    • 偏移量默认为0而非1。
  • 示例

    select * from orders_history where type=8 limit 1000,10;

    该语句将从orders_history表中查询第1000条数据之后的10条记录(即第1001条到第10010条)。

  • 默认排序: 数据表中的记录默认使用主键(通常为id)排序,上述结果相当于:

    select * from orders_history where type=8 order by id limit 10000,10;
  • 测试结果

    • 1条记录:3072ms 3092ms 3002ms
    • 10条记录:3081ms 3077ms 3032ms
    • 100条记录:3118ms 3200ms 3128ms
    • 1000条记录:3412ms 3468ms 3394ms
    • 10000条记录:3749ms 3802ms 3696ms
  • 随着每次请求的记录数增加,查询时间呈线性增长。可以看到,当每次查询的记录数低于100时,查询时间基本没有差异。但随着记录数的增加,查询时间显著增加。

    子查询优化

    这种优化方式通过先定位偏移位置的id,然后再向后查询,适用于id递增的情况。具体语句如下:

  • 获取单条记录的id

    select id from orders_history where type=8 limit 100000,1;
  • 根据id查询后续记录

    select * from orders_history where type=8 and id > (select id from orders_history where type=8 limit 100000,1) limit 100;
  • 测试结果

    • 单条记录查询:3674ms
    • id查询:1315ms
    • 后续记录查询(100条):1327ms
    • 后续记录查询(1000条):3710ms
  • 可以看出,通过使用select id代替select *,查询速度提高了3倍。子查询相较于普通分页查询,能够显著提升查询效率。

    id限定优化

    这种优化方式假设数据表的id是连续递增的,可以通过计算查询的id范围来实现分页查询。具体语法如下:

  • 基于范围查询

    select * from orders_history where type=2 and id between 1000000 and 1000100 limit 100;
  • 另一种写法

    select * from orders_history where id >= 1000001 limit 100;
  • 使用in子句

    select * from orders_history where id in (select order_id from trade_2 where goods = 'pen') limit 100;
  • 这种优化方式的优势在于可以直接定位到需要查询的记录范围,特别适用于已知id范围的情况。需要注意的是,某些MySQL版本不支持在IN子句中使用LIMIT

    临时表优化

    这种优化方式虽然不属于传统的查询优化,但值得提及。对于使用id限定优化中的场景,特别是在数据缺失或历史数据处理时,可以考虑使用临时存储的表来记录分页的id,然后通过IN子句查询。这种方法在数据量较大时能显著提升传统分页查询的速度。

    关于数据表的id说明

    一般情况下,数据库表中会强制添加一个递增的id字段,使得分页查询更加便捷。对于像订单库这样的数据量庞大,建议采取分库分表策略,并使用分布式的高并发唯一id生成器来生成唯一标识。

    最后

    欢迎在评论区留言交流,如果觉得文章有价值,请记得点赞支持!

    转载地址:http://rlvg.baihongyu.com/

    你可能感兴趣的文章
    nghttp3使用指南
    查看>>
    Nginx
    查看>>
    nginx + etcd 动态负载均衡实践(三)—— 基于nginx-upsync-module实现
    查看>>
    nginx + etcd 动态负载均衡实践(二)—— 组件安装
    查看>>
    nginx + etcd 动态负载均衡实践(四)—— 基于confd实现
    查看>>
    Nginx + Spring Boot 实现负载均衡
    查看>>
    Nginx + uWSGI + Flask + Vhost
    查看>>
    Nginx - Header详解
    查看>>
    Nginx - 反向代理、负载均衡、动静分离、底层原理(案例实战分析)
    查看>>
    nginx 1.24.0 安装nginx最新稳定版
    查看>>
    nginx 301 永久重定向
    查看>>
    nginx css,js合并插件,淘宝nginx合并js,css插件
    查看>>
    Nginx gateway集群和动态网关
    查看>>
    Nginx Location配置总结
    查看>>
    Nginx log文件写入失败?log文件权限设置问题
    查看>>
    Nginx Lua install
    查看>>
    nginx net::ERR_ABORTED 403 (Forbidden)
    查看>>
    Nginx SSL私有证书自签,且反代80端口
    查看>>
    Nginx upstream性能优化
    查看>>
    Nginx 中解决跨域问题
    查看>>