概述
问题: 项目每日游戏日志表数据量由原来1w+增长到千万级别,原先获取数据方式:
SELECT * FROM table
一次性取出的数据量太大导致内存溢出。既然一次性取数据不行,那就分次处理~
1-1. 使用LIMIT每次取5w条数据
SELECT * FROM table LIMIT 0,50000SELECT * 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 <= 50000SELECT * 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 #先取出并处理idSELECT * FROM table WHERE id IN (5000001,5000002,5000003,...)
速度可以接受,使用其它条件不通过索引查询速度相对还会慢一些,模块内每个字段都可以作为组合查询条件,所以没加索引,在项目页面上增加先缩小数据范围再查询的提示,搞定~
转载于:https://blog.51cto.com/yjm199/1844615
最后
以上就是文艺招牌为你收集整理的mysql查询速度的全部内容,希望文章能够帮你解决mysql查询速度所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复