Laravel优化总和查询

问题描述 投票:2回答:1

我想得到存款,取款和净计数。目前,我有~10,335,633行数据(~1.8GB),计算总和需要7秒多。我该如何改进查询以使其更快?

查询:

$depositQuery = Deposit::whereBetween('created_at', [$start, $end])->approved();
$withdrawQuery = Withdraw::whereBetween('created_at', [$start, $end])->approved();

if ($request->has('user_id')) {
    $depositQuery = $depositQuery->where('user_id', $request->user_id);
    $withdrawQuery = $withdrawQuery->where('user_id', $request->user_id);
}

$deposits = $depositQuery->sum('amount');
$withdraws = ($withdrawQuery->sum('amount')) * -1;
$net = $deposits + $withdraws;

结果:

Deposit     Withdraw     Net Amount
20,946.00   15,066.00    5,880.00
mysql laravel laravel-5.1
1个回答
2
投票

基本上,laravel eloquent与sum()的优化没有任何关系,它只是将您的代码转换为SQL查询。并进入你的问题

记住:你不能优化sum函数本身*(除非你是一些真正的jedi)

您的数据库中有1M条记录,并且MySQL sum必须通过所有记录来计算总和。在那种情况下,我认为7秒是可以的。根据here这个问题,sum()在7M记录表上花了大约22秒。所以取决于你的架构,机器等......速度可能会有所不同。

那么如何才能继续改善响应时间?

不知何故,在将数据提供给sum()进行处理之前,您必须减少记录数量。

我认为你可以做的一种方法是,你可以计算10k记录批次/块的总和,并将其存储在一个单独的表中,具有适当的日期和时间范围。这方面的广义术语是归档。然后,当您必须计算给定日期范围的总和时,请使用新表中的前一个完整总和并使用它。您可以设置一个计时作业,以便在一天内更新此表,或者确保数据始终正确。

另一种方式是partition MySQL tables。这也似乎是一种很有前途的方式。这也是一种归档。但我对它的评论不是很有经验。谷歌应该帮助你。

created_at这样的列的索引以及用于批准范围的列应该可以改善响应时间,但不会像利用归档技术那样多。

另外,我在上面指定的同一链接more info的答案中有MySQLmysql查询缓存。哪个你可以试试用。但是,从mysql 8开始,它已被弃用,而且,如果你有多个实例正在运行并且你有分区表,它将无法正常工作。

© www.soinside.com 2019 - 2024. All rights reserved.