laravel - Laravel Eloquent 查询 200 万行需要很长时间
问题描述
我必须从有 200 万行的表中提取数据。雄辩的查询如下所示:
$imagesData = Images::whereIn('file_id', $fileIds)
->with('image.user')
->with('file')
->orderBy('created_at', 'DESC')
->simplePaginate(12);
中使用的$fileIds
数组whereIn
可以包含 100 甚至 1000 的文件 ID。
上面的查询在小表中工作正常。但是在Images
表中超过 200 万行的生产站点中,需要 15 秒以上才能得到回复。我仅将 Laravel 用于 api。
我已阅读有关此主题的其他讨论。我paginate()
改为simplePaginate()
. 一些建议也许有一个DB::
查询whereRaw
可能比whereIn
. 有人说这可能是由于处理时 php 中的 PDOwhereIn
和一些建议使用Images::whereIn
我已经使用过的。
我使用 MariaDB,InnoDB 用于 db 引擎并将其加载到 RAM 中。sql 查询对所有其他查询执行良好,但只有那些必须从像这样的大表中收集数据的查询才需要时间。
如何优化上述 laravel 查询,以便在表有数百万行时将查询响应减少到几秒钟?
解决方案
您需要索引,它按某些列对数据进行分段。您正在访问file_id
和created_at
。因此,以下索引将有助于提高性能。
$table->index(['file_id', 'created_at']);
索引会增加插入时间,并使查询具有奇怪的执行计划。如果您EXPLAIN
在执行查询之前和之后对查询使用 SQL,我们可以验证它有助于解决问题。
推荐阅读
- css - 保证金没有在 div 上给出任何结果
- reactjs - 反应 this.state 为空
- c# - 使用 ShouldSkipRecord 过滤 CSVHelper 中的日期范围
- rest - IDDD 红皮书:第 13 章集成限界上下文,RESTful 时间解耦
- mysql - 如何将 Web 应用程序链接到 MySQL Azure 数据库?
- arrays - 围绕数组中的最大值进行分区的算法的最佳和最坏情况是什么?
- python - 在pygame中按住鼠标单击时如何阻止变量增加
- javascript - AngularJS + webpack如何散列模板html
- python - 使用 einsum 在傅立叶域中实现 conv2d --> ValueError: einstein sum subscripts string contains too many subscripts for operand 0
- reactjs - 如何在
标签?