SQL Laravel 5.7 收集时的 unique() 真的很慢

SQL Laravel 5.7 unique() on collection really slow

我正在尝试根据 mobile 列计算唯一记录的数量,该列通过 Laravel collectunique 方法具有索引。我有 200,000 行,并且有一个名为 optout_csv_schedule_id 的列,它与移动设备一起有一个索引。现在,执行查询已经 运行 超过 15 分钟,我如何提高它的性能,因为我需要计算 200,000 中唯一数字的数量,我当前的查询是:

/**
 * Get valid lead count
 */
protected function getValidLeadCount($schedule_id)
{
    $optoutConnectionLogs = OptoutConnectionLog::where('optout_csv_schedule_id', $schedule_id)
                                               ->get();

    // no leads
    if (!$optoutConnectionLogs) {
        return 0;
    }

    // count total unique leads
    $uniqueLeads = collect($optoutConnectionLogs)->unique('mobile')->count();
    return $uniqueLeads;
}

您没有使用数据库来做唯一性,您已经用 ->get() 获得了记录,并且正在使用 PHP/Laravel 来做。这将比使用数据库慢 很多。

使用distinct()获取唯一记录,例如:

$optoutConnectionLogs = OptoutConnectionLog::where('optout_csv_schedule_id', $schedule_id)
    ->select('mobile')
    ->distinct()
    ->get();

你把所有数据读入内存,转换成PHP个对象,然后迭代计数。您创建的数据库索引根本没有被使用。

你的需求应该简化成下面的代码

return OptoutConnectionLog::where('optout_csv_schedule_id', $schedule_id)
                           ->distinct('mobile')
                           ->count();

Laravel的200,000个中,似乎很难计算出唯一数字的数量。 尝试更改如下:

protected function getValidLeadCount($schedule_id)
{
    $uniqueLeads = OptoutConnectionLog::where('optout_csv_schedule_id', $schedule_id)
                                                 ->distinct('mobile')
                                                 ->count('mobile');
    return $uniqueLeads;
}