MySQL大数据LIMIT优化

针对游戏日志表数据量激增至千万级别的挑战,本文档介绍了如何通过分批查询、利用主键ID及子查询等手段优化数据获取过程,有效避免内存溢出问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题: 项目每日游戏日志表数据量由原来1w+增长到千万级别,原先获取数据方式:

SELECT * FROM table

一次性取出的数据量太大导致内存溢出。既然一次性取数据不行,那就分次处理~
 
1-1. 使用LIMIT每次取5w条数据

SELECT * FROM table LIMIT 0,50000
SELECT * FROM table LIMIT 50000,50000
...

重新跑了代码,速度很慢,可能是处理数据耗时过长,数据表内有一大部分是此处无用的重复数据,从这入手~
 
1-2. 根据项目情况通过SELECT DISTINCT减少得到的数据量
加上索引后速度不错,但是INDEX_LENGTH大约是DATA_LENGTH的75%左右。
索引占了太大空间,只能另想他法 ╮(╯▽╰)╭
 
发现一个奇怪现象:

SELECT * FROM table LIMIT 0,50000 #速度很快
SELECT * FROM table LIMIT 5000000,50000 #速度很慢


此表有自增id主键,所以使用WHERE条件可以顺利解决~
 
1-3. 通过WHERE条件按自增id取数据

SELECT * FROM table WHERE id > 0 AND id <= 50000
SELECT * FROM table WHERE id > 50000 AND id <= 100000
...


搞定~ 但是还有一个模块需要使用其它查询条件,最终结果id不连续,得另想个办法。
 
基于:

SELECT * FROM table LIMIT 5000000,1 #速度相对较快
SELECT * FROM table LIMIT 5000000,50000 #速度很慢


2-1. 先取第一条id 再通过id与LIMIT取数据

SELECT * FROM table WHERE condition AND id >= (SELECT id FROM table WHRER condition LIMIT 5000000,1) LIMIT 50000

速度提升,但不理想。
 
2-2. 先通过子查询取出id 再通过id取数据

SELECT * FROM table WHERE id IN (SELECT id FROM (SELECT id FROM table WHERE condition LIMIT 5000000,50000) AS tmp)

先通过主键索引找出id,再通过id取数据,测试结果不理想,但是SQL和子查询分开执行,速度ok。
 
2-3. 拆分成两次执行 先取出id 再通过id取数据

SELECT id FROM table WHERE condition #先取出并处理id
SELECT * FROM table WHERE id IN (5000001,5000002,5000003,...)

速度可以接受,使用其它条件不通过索引查询速度相对还会慢一些,模块内每个字段都可以作为组合查询条件,所以没加索引,在项目页面上增加先缩小数据范围再查询的提示,搞定~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值