简单查询在 laravel 中很慢(带有分页)但在 phpmyadmin 中非常快

Posted

技术标签:

【中文标题】简单查询在 laravel 中很慢(带有分页)但在 phpmyadmin 中非常快【英文标题】:Simple query is slow in laravel (with paginate) but very fast in phpmyadmin 【发布时间】:2021-12-14 08:04:40 【问题描述】:

我看过类似的问题,我得到的答案是在我的查询中设置限制,我这样做了。

这里是查询

  $sql = DB::table('inventorysku_tb as isku')
     ->leftJoin('inventorytrackingmodules_tb as itm', function ($join) 
        $join->where('itm.coID', '=', 4)
           ->whereBetween('itm.effectiveDate', ['2021-05-01', '2021-05-31'])
           ->on('itm.skuID', '=', 'isku.ID');
     )


  $sql->paginate(25);

  return $sql;

这个查询大约需要 17 秒才能运行,现在如果我在上面的查询上运行 ->toSql() 并将其粘贴到 phpmyadmin(更改 ? 值)

select * 
from `inventorysku_tb` as `isku` 
    left join `inventorytrackingmodules_tb` as `itm` 
        on `itm`.`coID` = 4
        and `itm`.`effectiveDate` between '2021-05-01' and '2021-05-31'
        and `itm`.`skuID` = `isku`.`ID`

这个在phpmyadmin中运行只需要0.2秒...

laravel代码上就这些了,上面没有其他代码了……

另一个奇怪的事情是,如果我在 laravel 中将左连接改为内连接,查询现在很快(878 毫秒)..

【问题讨论】:

嘿,你可以尝试一些事情。首先,您可以使用Laravel Debugbar,它将显示在每个页面上运行的查询,并使您更容易调试。另一件可能有帮助的事情是在您的表上添加索引。 【参考方案1】:

根据Laravel doc: on 子句可以链接起来,例如

$join->on('contacts.user_id', '=', 'users.id') ->on('contacts.info_id', '=', 'info.id')

将产生以下 SQL:

on contacts.user_id = users.id and contacts.info_id = info.id

所以,对于你的情况,代码可能是:

$sql = DB::table('inventorysku_tb as isku')
     ->leftJoin('inventorytrackingmodules_tb as itm', function ($join) 
        $join->on('itm.coID', '=', 4)
           ->on(function ($query)
                $query->whereBetween( 'itm.effectiveDate',['2021-05-01',
                   '2021-05-31']);
           ->on('itm.skuID', '=', 'isku.ID');
     )

这样,我认为您可以生成与在 phpMyAdmin 中使用的查询相同的查询

【讨论】:

【参考方案2】:

删除LEFT。由于您在WHERE 中进行了限制,因此它是JOIN

将此添加到itmINDEX(coID, skuID, effectiveDate)

【讨论】:

以上是关于简单查询在 laravel 中很慢(带有分页)但在 phpmyadmin 中非常快的主要内容,如果未能解决你的问题,请参考以下文章

sql查询在Hibernate中很慢,在mysql上很快

带有雄辩查询的 Laravel 分页

Laravel Livewire 分页

使用 Laravel 将两个模型合并到一个分页查询中,并带有急切加载的关系

一个数据库的查询速度很慢,但在他的副本上查询速度很快

数据量很大,分页查询很慢,优化方案