MySQL深分页问题原理与三种解决方案

目录 1 深分页问题 1.1 创建表 1.2 新增100万条数据 1.3 深分页语句 1.4 结果分析 2 深分页优化方案 2.1 方案一 2.2 方案二 2.2.1 优化语句 2.2.2 执行计划 2.2.3 结果分析 2.3 方案三 2.3.1 优化语句

                        目录1 深分页问题1.1 创建表1.2 新增100万条数据1.3 深分页语句1.4 结果分析2 深分页优化方案2.1 方案一2.2 方案二2.2.1 优化语句2.2.2 执行计划2.2.3 结果分析2.3 方案三2.3.1 优化语句2.3.2 执行计划3 MyBatis4 文章总结<p></p>

1 深分页问题

1.1 创建表

CREATE TABLE player ( id bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', player_id varchar(256) NOT NULL COMMENT '运动员编号', player_name varchar(256) NOT NULL COMMENT '运动员名称', height int(11) NOT NULL COMMENT '身高', weight int(11) NOT NULL COMMENT '体重', game_performance text COMMENT '最近一场比赛表现', PRIMARY KEY (id) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8

1.2 新增100万条数据

@SpringBootTest(classes = TestApplication.class) @RunWith(SpringJUnit4ClassRunner.class) public class PlayerServiceTest {

@Resource
private PlayerRepository playerRepository;

@Test
public void initBigData() {
    for (int i = 0; i &lt; 1000000; i++) {
        PlayerEntity entity = new PlayerEntity();
        entity.setPlayerId(UUID.randomUUID().toString());
        entity.setPlayerName("球员_" + System.currentTimeMillis());
        entity.setWeight(150);
        entity.setHeight(188);
        entity.setGamePerformance("{"runDistance":8900.0,"passSuccess":80.12,"scoreNum":3}");
        playerRepository.insert(entity);
    }
}

}

1.3 深分页语句

select * from player limit 990000,5

1.4 结果分析

查询耗时:1.233秒本语句目标查询[990001-990005]五条数据但是执行时需要排序[1-990005]数据最终丢弃[1-990000]只返回[990001-990005]数据

2 深分页优化方案

2.1 方案一

我们可以从业务形态维度去解决,可以参考搜索引擎解决方案。因为ES也存在深分页问题,搜索引擎解决方案是在业务上会限制查询页数。因为页数越大,内容相关度越低,所以页数太大对业务价值不高。MySQL可以类比处理:

限制查询页数限制全量导出查询时要求带必要条件(时间范围、userId)

2.2 方案二