Nee*_*eel 6 indexing mariadb laravel eloquent laravel-5
我必须从一个有 200 万行的表中提取数据。雄辩的查询如下所示:
$imagesData = Images::whereIn('file_id', $fileIds)
->with('image.user')
->with('file')
->orderBy('created_at', 'DESC')
->simplePaginate(12);
Run Code Online (Sandbox Code Playgroud)
中使用的$fileIds数组whereIn可以包含 100 甚至 1000 个文件 ID。
上述查询在小表中工作正常。但是在Images表中有超过 200 万行的生产站点中,需要超过 15 秒才能得到回复。我仅将 Laravel 用于 api。
我已阅读有关此主题的其他讨论。我换paginate()到simplePaginate()。一些人建议也许有一个DB::查询whereRaw可能比whereIn. 有人说这可能是由于处理时 php 中的 PDO 而whereIn有些人建议使用Images::whereIn我已经使用过的。
我使用 MariaDB,将 InnoDB 用于数据库引擎并将其加载到 RAM 中。sql 查询对于所有其他查询都表现良好,但只有那些必须从像这样的大表中收集数据的查询才需要时间。
我如何优化上面的 Laravel 查询,以便在表有数百万行时,如果可能的话,我可以将查询响应减少到几秒钟?
您需要索引,它按某些列对您的数据进行分段。您正在访问file_id和created_at。因此,以下索引将有助于提高性能。
$table->index(['file_id', 'created_at']);
Run Code Online (Sandbox Code Playgroud)
索引会增加插入时间,并使查询具有奇怪的执行计划。如果您EXPLAIN在执行查询之前和之后在查询上使用 SQL ,我们可以验证它是否有助于解决问题。
以下是为加快页面加载而采取的步骤的更新。
如此缓慢的查询的真正罪魁祸首不仅仅是上面的特定查询。上述查询获取数据后,php 会迭代数据并在其中执行子查询来检查某些内容。此查询在每次迭代期间使用filename列来搜索数据。由于filename是字符串且未索引,因此该控制器的响应时间花费了很长时间,因为每个子查询都在循环内爬行 150 万行foreach。一旦我删除了这个子查询,加载时间就减少了很多。
其次,我按照上面@mrhn和@ceejayoz的建议file_id添加了索引。created_at我创建了一个这样的迁移文件:
Schema::table('images', function (Blueprint $table) {
$table->index('file_id', 'created_at');
});
Run Code Online (Sandbox Code Playgroud)进一步优化PHP脚本。我删除了所有使用 进行搜索的查询fileNames,并将其更改为使用id来获取结果。这样做对整个应用程序产生了巨大的影响,并且由于高峰时段 CPU 工作量减少,还提高了服务器速度。
最后,我通过执行以下步骤优化了服务器:
当我编辑完上述所有步骤后,我发现加载速度存在巨大差异。结果如下:
感谢所有对此发表评论的人。您的评论帮助我执行了上述所有步骤,结果是富有成效的。谢谢大家。
| 归档时间: |
|
| 查看次数: |
4385 次 |
| 最近记录: |