为了账号安全,请及时绑定邮箱和手机立即绑定

mysql查询导致内存过大问题

mysql查询导致内存过大问题

湖上湖 2019-02-25 04:32:20
在查询数据库的时候,由于数据量大,我要做分页,然后首先获取总的条数,但是使用sql语句SELECT COUNT(*) as total from 表 WHERE addtime between 1164038401 and 1511235339;这条sql等于遍历了全表,数据有一百万条,id为主键索引,addtime为普通索引。现在问题是一使用这条语句内存使用量就从一开始的30%多直接上升到90%多,怎么解决这个内存问题?我现在只是查询个数,但是分页的时候会查询有条件的大量数据,对于内存过大,有什么好的解决办法?比如sql不使用缓存,修改配置文件等等。求大神指导,谢谢!
查看完整描述

8 回答

?
肥皂起泡泡

TA贡献1829条经验 获得超6个赞

对于几百万行+的大表来说,COUNT(*)是非常耗时的,你看能不能换个方式处理下。

要么在业务上索性就不统计,你想想你做分页,每页10条数据,两百万行就是 20 万页,你统计了别人会翻这么多页吗。

另一种方式就是如果你的主键是连续递增的,就可以通过边界值相减得到统计结果,这比你直接 count 肯定是减少了不少时间。

查看完整回答
反对 回复 2019-03-01
?
qq_笑_17

TA贡献1818条经验 获得超7个赞

100w行数据,你内存又不够,分表吧,分成十个。
然后判断哪几个表在时间区间内有数据(查询第一个和最后一个数据即可判断)
最后只在这几个表中查询,汇总,这样大概能减少80%的内存占用和时间。
如果还嫌速度慢,那就大数据,多台服务器并发查询各自的子表,最后加和。

查看完整回答
反对 回复 2019-03-01
?
森林海

TA贡献2011条经验 获得超2个赞

1、数量,@rift说的对,你做分页页数太多别人也不会翻这么多页

2、分页查询数据可以分为两步吧
1) select id from XXX where xxx=xx;
2) select * from XXX where id in (ids)
这样查询会好些

查看完整回答
反对 回复 2019-03-01
?
函数式编程

TA贡献1807条经验 获得超9个赞

建议使用MySQL分区表,用addtime作为分区字段,不要任何索引。查询的时候带分区字段,确保查询扫描的分区表个数在一个很少的数量。这个方案不需要改动数据表结构和改动代码,实施成本低,效果很不错。

查看完整回答
反对 回复 2019-03-01
?
波斯汪

TA贡献1811条经验 获得超4个赞

如果 id 是连续的,可以使用 id 作为分页依据

SELECT field FROM table_name WHERE `id` < num1 and `id` > num2

或者, id + limit 配合使用

SELECT field FROM table_name WHERE `id` > num LIMIT page_size

这样做的目的:

  • 大数据量时,LIMIT OFFSET 效率太低

  • id 唯一,自增,效率高于普通索引

查看完整回答
反对 回复 2019-03-01
?
慕容708150

TA贡献1831条经验 获得超4个赞

你explain这条查询语句,由于count(*),type字段肯定是All,所以肯定是走全表的,但是如果你是count(id),应该会是ref,因为addtime你加索引了。

查看完整回答
反对 回复 2019-03-01
?
收到一只叮咚

TA贡献1821条经验 获得超4个赞

select查询的时候尽量不要使用*
查看完整回答
反对 回复 2019-03-01
  • 8 回答
  • 0 关注
  • 1390 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信