【问题标题】:Slow query in laravellaravel 中的慢查询
【发布时间】:2020-01-16 13:41:22
【问题描述】:

我有一个 laravel 应用程序,但是一个查询需要很长时间才能执行。

我尝试构建原始查询但没有成功。

查询是这个:

$utente = Utente::with('coll')->with('collaboratori')
            ->where('id', '<>', '0')
            ->whereHas('coll', function ($query) use($id_utente, $att_dummy){
                $query->where('collaboratori_id', 'like', $id_utente);})
            ->orderBy('created_at')
            ->get();

我还尝试使用 queryLog 查看 sql 查询,laravel 执行了不同的查询:


select * from `utenti_nuovo` where `id` <> 0 and exists (select * from `collaboratori_utenti` where `utenti_nuovo`.`id` = `collaboratori_utenti`.`id_utente` 
and `collaboratori_id` like 100008) order by `created_at` asc

select * from `collaboratori_utenti` where `collaboratori_utenti`.`id_utente` in (718, 834, 844, 848, 875, 890, 894, 895, 897, 898)

select * from `collaboratori` where `collaboratori`.`id` in (12,13,16)

select `collaboratori`.*, `collaboratori_utenti`.`id_utente` as `pivot_id_utente`, `collaboratori_utenti`.`collaboratori_id` as `pivot_collaboratori_id`, 
`collaboratori_utenti`.`attivita` as `pivot_attivita`, `collaboratori_utenti`.`created_at` as `pivot_created_at`, `collaboratori_utenti`.`updated_at` as `pivot_updated_at` 
from `collaboratori` inner join `collaboratori_utenti` on `collaboratori`.`id` = `collaboratori_utenti`.`collaboratori_id` 
where `collaboratori_utenti`.`id_utente` in (718, 834, 844, 848, 875, 890, 894, 895, 897, 898)

这些查询中的第一个是导致很长时间等待的慢查询。

有没有办法通过更快的查询来更改 EXIST?

【问题讨论】:

  • 我认为加入会更有效率...
  • 尝试将 ` 'like', $id_utente` 更改为 ` '=', $id_utente`
  • 你为什么用like而不是=?
  • 使用like会避免mysql使用索引。另外,你的 colaboratori_id 上有索引吗?波那血清!
  • 每张表有多少行?

标签: laravel eloquent


【解决方案1】:

仅选择您需要的字段。这将减少加载时间。

【讨论】:

  • 不会对查询速度造成太大影响。
【解决方案2】:

为了优化查询时间,可以使用laravel cursors。不要以-&gt;get() 结束查询,只需使用-&gt;cursor(),如下所示:

$utente = Utente::with('coll')->with('collaboratori')
    ->where('id', '<>', '0')
    ->whereHas('coll', function ($query) use($id_utente, $att_dummy){
        $query->where('collaboratori_id', 'like', $id_utente);})
    ->orderBy('created_at')
    ->cursor();

使用大型数据库时,最好使用cursor。下面是使用get、chunk和cursor的对比,from this answer

10,000 条记录:

+-------------+-----------+------------+
|             | Time(sec) | Memory(MB) |
+-------------+-----------+------------+
| get()       |      0.17 |         22 |
| chunk(100)  |      0.38 |         10 |
| chunk(1000) |      0.17 |         12 |
| cursor()    |      0.16 |         14 |
+-------------+-----------+------------+

100,000 条记录:

+--------------+------------+------------+
|              | Time(sec)  | Memory(MB) |
+--------------+------------+------------+
| get()        |        0.8 |     132    |
| chunk(100)   |       19.9 |      10    |
| chunk(1000)  |        2.3 |      12    |
| chunk(10000) |        1.1 |      34    |
| cursor()     |        0.5 |      45    |
+--------------+------------+------------+

【讨论】:

    猜你喜欢
    • 2020-10-30
    • 1970-01-01
    • 2021-04-11
    • 2020-03-04
    • 2021-06-23
    • 2021-04-01
    • 2017-11-17
    • 2018-02-27
    • 1970-01-01
    相关资源
    最近更新 更多