关于 eloquent 查询数据库表的问题
做一个有36W条数据的数据库table,
$customerHistory = SO::where('id'$id)->get();
用eloquent 去搜索 获得大约2W条数据,用get()获得。
在localhost 上用的时候很OK,
但是上传了 shared host 总是会报错 internal error 500
但是加了$customerHistory = SO::where('id'$id)->limit(5000)->get() 就好;
但是加5W 又报错
目测是内存溢出了,把PHP的内存限制改大一点
第一:这么做不太合理,一次取这么多数据不对,建议你考虑分页。
第二:出现500的错误,想办法打印详细出错日志,这样乱猜很消耗你的体能和信心。
建议使用
chunk()
或者cursor()
来读取大量数据库记录,避免内存读满。详细比较可以看这篇 Laravel(Eloquent): chunk() vs cursor() :tada:@leo 谢谢大神 今天下午我搞出来了 就是 PHP 内存溢出了。。最后设置到256mb的 memory 才能运行。
@young 谢谢啦
@lijinma 不是要分页展示出来, 而是在37万条数据里 搜出来结果大约2w条, 然后每一条里有一个column是 消费金额, 我需要把这两万条的加起来
@young 还是日语- -。。。。
@咖啡是個軟件猴 为何不直接用
sum
@leo 您说的直接用是 直接用什么?
@咖啡是個軟件猴 sql里用sum求和呀
@leo 对呀 你说的有道理, 新手完全不懂这些 哈哈 刚开始接触3个月
public function customerHistory(){
求哪个大神给看看 我这个是不是逻辑上有问题, 所以导致了 很慢, 因为我这个要计算出每个月的销售总额。。
@young 文中作者提到cursor的方式,一条一条查询,内存按理应该是最小和不变的,但是事实并非如此。对于这点我也有困惑,可惜作者没有解释原因,请问你知道原因吗?
@CoderPoet 我觉得原文作者的说法有错误,其实
cursor
并不是像文章说的那样一条一条的查询。他和all()
一样,都是一次查询,得到所有数据select * from "users"
。之所以占内存小是因为,他不是直接输出数组供foreach
循环,而是使用了 yield 生成器 来输出数据。其实文章说的也对,yield
的语法就是一条一条的输出数据。所以要明白cursor
的优化原理不像chunk
,多次查询减少内存,而是一次查询,使用生成器输出数据来减少内存占用。@young 感谢!豁然开朗了!难怪使用cursor的时候,内存会先吃掉一大块,然后又持续不断往上涨。不过总体还是比直接all()消耗的内存小。
另外再想请问下,使用cursor的时候 是第一次就从数据库查到所有数据么,所以内存会吃掉一大块;那么之后得持续不断上涨的内存有什么办法优化?我试过unset变量 ,刷新Buffer,都没效果,而且困惑的是这块内存的消耗是来自于什么?