laravel 中的慢查询
Posted
技术标签:
【中文标题】laravel 中的慢查询【英文标题】:Slow query in laravel 【发布时间】: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 上有索引吗?波那血清! 每张表有多少行? 【参考方案1】:仅选择您需要的字段。这将减少加载时间。
【讨论】:
不会对查询速度造成太大影响。【参考方案2】:为了优化查询时间,可以使用laravel cursors。不要以->get()
结束查询,只需使用->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 | +--------------+------------+------------+
【讨论】:
以上是关于laravel 中的慢查询的主要内容,如果未能解决你的问题,请参考以下文章
Django 慢查询:将 django 过滤语句连接到数据库日志中的慢查询
phpMyAdmin中的慢查询但Mysql慢查询日志文件中没有[关闭]