【问题标题】:Getting last item in groupBy获取 groupBy 中的最后一项
【发布时间】:2018-05-17 15:20:22
【问题描述】:

我在这里找到了一些我遵循的答案,发现它在本地工作,所以我推到我们的测试框,我发现这个特定的数据库查询通过进入 mysql 和 @987654321 持续超过 1300 秒@它挂在copying to tmp table

它是 Laravel 4.2,相当古老的遗留代码,我只是想在开发更高版本时稳定它。下面的代码根据 api_call 大约每 30 秒重复一次,这一切都很好,除了它没有完成并收到 504 Gateway Time-out 我觉得我正在做一些递归的事情,或者在这里搜索一个非常大的数据库会是一个问题吗?

我想要做的只是运行一个 groupBy,但不是按第一个分组,而是按最后一个分组,以防其他详细信息被更新。

我们将非常感谢您提供的任何帮助。

public function api_prevnames()
{
    if (Auth::user()->repeat_vistor == 'Y') {
        $names = DB::table('visitors')
            ->select(DB::raw('first_name,last_name,email,car_reg,OPTIN,vistor_company'))
            ->where('user_id', Auth::user()->id)
            ->where('hidden', 0)
            ->where('email', '<>', '')
            ->whereRaw('id IN (select MAX(id) FROM visitors GROUP BY first_name, last_name, email)')
            ->get();
    }

    return JSONResponseGenerator::successResponse($names->toArray());

}

生成此查询

select first_name,last_name,email,car_reg,OPTIN,vistor_company from `visitors` where `user_id` = '439' and `hidden` = '0' and `email` <> '' and id IN (select MAX(id) FROM visitors GROUP BY first_name, last_name, email)

之前的代码运行不到几秒钟,我在下面添加了这些代码:

            $names = DB::table('visitors')
            ->select(DB::raw('first_name,last_name,email,car_reg,OPTIN,vistor_company'))
            ->where('user_id', Auth::user()->id)
            ->where('hidden', 0)
            ->where('email', '<>', '')
            ->groupBy('first_name', 'last_name', 'email')
            ->get();

【问题讨论】:

    标签: php mysql sql laravel eloquent


    【解决方案1】:

    您可以尝试运行以下命令:

    SELECT
        first_name,
        last_name,
        email,
        car_reg,
        OPTIN,
        vistor_company
    FROM (
        SELECT
            MAX(id) AS id
        FROM `visitors`
        WHERE
            `user_id` = 439
            AND `hidden` = 0
            AND `email` <> ''
        GROUP BY
            first_name,
            last_name,
            email
    ) AS subQ
    NATURAL JOIN `visitors`;
    

    加入通常比其他方式更快,但我认为这不会有帮助,因为您显然没有按索引分组。为此,您必须更改结构,我强烈建议您这样做。尽量减少 first_name、last_name 和 email 的最大长度,这样就可以创建这三者的组合索引。如果您可以在不杀死一半系统的情况下更改数据库结构本身,则应考虑规范化该表,例如有一个带有访问者的表和另一个带有这些访问者访问的表(与外键的关系),因此您可以按键分组由三个长度很大的未索引字符串分组。

    【讨论】:

    • Here is an imgur of the table/query上面的文字查询我也加了。
    • 绝对粉碎它的伙伴,完全符合我的需要,而且速度也很快!
    • 我已经更新了您的编辑,以添加我在 Laravel 中修复此问题的确切过程。非常感谢您的帮助。
    猜你喜欢
    • 2021-06-25
    • 2016-12-12
    • 2010-09-06
    • 2011-04-28
    • 2011-03-14
    • 1970-01-01
    • 1970-01-01
    • 2016-02-15
    • 2011-05-18
    相关资源
    最近更新 更多