MySQL大数据分页优化方案

避免使用LIMIT偏移量过大 传统分页LIMIT 1000000, 20会导致MySQL扫描前100万条记录。替代方案:

SELECT * FROM table WHERE id > 1000000 ORDER BY id LIMIT 20

使用覆盖索引 确保查询只通过索引完成:

SELECT id FROM table ORDER BY id LIMIT 1000000, 20

延迟关联 先通过索引定位,再关联原表:

SELECT t.* FROM table t
JOIN (SELECT id FROM table ORDER BY id LIMIT 1000000, 20) tmp
ON t.id = tmp.id

Java分页查询实现

MyBatis分页插件 配置PageHelper实现物理分页:

PageHelper.startPage(pageNum, pageSize);
List<User> users = userMapper.selectAll();
PageInfo<User> pageInfo = new PageInfo<>(users);

JPA分页接口 使用Spring Data JPA的分页对象:

Pageable pageable = PageRequest.of(page, size, Sort.by("id").desc());
Page<User> userPage = userRepository.findAll(pageable);

缓存策略设计

多级缓存架构

  • 本地缓存(Caffeine/Ehcache):缓存热点数据
  • 分布式缓存(Redis):共享缓存层
  • 数据库缓存:查询结果缓存

缓存更新策略

@Cacheable(value="users", key="#page+'_'+#size")
public Page<User> getUsers(int page, int size) {
    return userRepository.findAll(pageRequest);
}

@CacheEvict(value="users", allEntries=true)
public void updateUser(User user) {
    userRepository.save(user);
}

分页缓存键设计 采用业务标识_页码_每页数量的格式:

String cacheKey = "user_list_" + pageNum + "_" + pageSize;

性能监控与调优

慢查询分析 开启MySQL慢查询日志:

SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;

Explain工具使用 分析查询执行计划:

EXPLAIN SELECT * FROM table WHERE condition LIMIT 10000, 20;

连接池配置优化 调整HikariCP参数:

spring.datasource.hikari.maximumPoolSize=20
spring.datasource.hikari.connectionTimeout=30000

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐