场景:APP或者小程序订单列表下拉刷新的时候偶尔间会出现订单号完全一模一样的订单,排查后数据库表查询确实只有一条,究竟什么原因导致的呢,大多人都一头雾水!
其实这个和mySql的底层分页逻辑有关。下面我们通过mysql做个简单测试.
一、问题复现:
新建订单模拟表,使用下面脚本.
CREATE TABLE`order` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ctime` bigint(20) NOT NULL COMMENT '修改时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
# 数据初始化
INSERT INTO`order`(`ctime`)VALUES (1);
INSERT INTO`order`(`ctime`)VALUES (2);
INSERT INTO`order`(`ctime`)VALUES (3);
INSERT INTO`order`(`ctime`)VALUES (4);
INSERT INTO`order`(`ctime`)VALUES (5);
INSERT INTO`order`(`ctime`)VALUES (6);
INSERT INTO`order`(`ctime`)VALUES (7);
INSERT INTO`order`(`ctime`)VALUES (8);
INSERT INTO`order`(`ctime`)VALUES (9);
INSERT INTO`order`(`ctime`)VALUES (10);
二、分页查询
1. SELECT * FROM `order` ORDER BY ctime DESC limit 0,5;
# 查询结果
id ctime
10 10
9 9
8 8
7 7
6 6
手机页面展示
10 9 8 7 6
2. 于此同时我们插入2条新增数据
INSERT INTO`order`(`ctime`) VALUES (11);
INSERT INTO`order`(`ctime`) VALUES (12);
3. 我们紧接着查询第二页
SELECT * FROM `order` ORDER BY ctime DESC limit 5,5;
查询结果
id ctime
7 7
6 6
5 5
4 4
3 3
重复数据: 6和7
手机页面展示
10 9 8 7 6, 7 6 5 4 3
原因:
查询第一页完后,获取到的数据是6~10,随后新增11和12两条数据,进 行查询第二页, 获取到的数据是3~7,此时6和7被 重复拉取 了
同理它也会遇到第二种问题分页查询:删除导致缺失。
图文理解:

解决方案:
一、记录时间点
查询出当前页数据后,记录下本次拉取位置(curPosition),当页数据和curPosition一并返回客户端;下次请求时,需要把上次获取的curPosition传给后端,后端从curPosition开始分页。
拉取位置:最好是当前排序字段。
二、全量更新,重新渲染
- 每次分页查询时候,返回当前页和当前页面之前所有页面的数据。limit 0,pageSize*pageNum
- 每次分页查询完,客户端重新渲染所有数据。
三、客户端分页
第一次进入订单列表时,请求接口查询得到所有数据,在客户端进行分页展示。此 后再往下划时,不需要再请求后端了,只需要把第一次请求后的数据展示出来即可。
该方法实在太不常见,弊端太明显,不建议使用。
|
展示数据实时性 |
请求次数 |
前后端压力 |
数据库压力 |
|
|
方法一 |
查询瞬间 |
一次一查 |
正常 |
正常 |
|
方法二 |
与数据库同步 |
一次一查 |
前端压力大 |
数据量随次数逐渐增多 |
|
方法三 |
第一次进入页面瞬间 |
查一次 |
前端压力大 |
一次请求大量数据 |