文章转发自专业的Laravel开发者社区,原始连接:learnku.com/laravel/t/2…laravel
下一个版本的 Laravel Scout 将会使你的模型查询速度提高64倍。git
我使用null scout 驱动测试了一张包含 1,632,576条数据的表。消耗的时间从过去的29分57秒缩短到了28秒。 [1]^github
你能在这里 查看提交的 pull request.数据库
这篇文章解释了为何代码中的这个更改会带来这么大的变化。这是我在我本身的 Laravel 应用中用来加速存在问题的查询的一个技巧。一旦你理解了它的原理,我打赌你会找到一种新的优化你的应用的方式。bash
默认状况下, Scout 会检索数据库中的每一行。为了保持内存使用的合理性,它使用 chunk
方法 一次只取几百行。post
chunk
方法为你的查询添加了限制和偏移量,像这样:测试
select * from `users` order by `id` asc limit 500 offset 500;
复制代码
要获取下一页,偏移量会递增。优化
select * from `users` order by `id` asc limit 500 offset 1000;
复制代码
首先这很好用,这个查询大约只须要大约一毫秒,但你走的越远,它就越慢。ui
一旦偏移量达到了 1,000,000 ,查询速度就会很容易慢 500 倍。当 Scout 导入执行数千个这样的查询时,它会累加起来。spa
当你使用偏移量时,你是在告诉数据库要跳过前 N 行。即便没有返回跳过的这些行,数据库仍然会从磁盘读取它们并对它们进行排序。
数据库 可能 可以使用索引并避免获取整个行。咱们的示例查询中使用主键索引,但仍然能够抓取。
事实证实,不使用偏移量就能够很容易地对结果进行分页。咱们所要作的就是跟踪咱们看到的最后一个 ID ,而后过滤结果,以便只获取咱们未见到的行。若是结果是按 ID 升序排序的,咱们可使用一个简单的 WHERE ID > :last_id
子句进行筛选。查询语句最终就会是像这样:
select * from `users` where `id` > :last_id order by `id` asc limit 500;
复制代码
使用这种技术后,加载最后一页和第一页加载速度是同样快。
Laravel 让这绝不费力。不要调用 chunk
而是调用 chunkById
方法(在 5.2 中添加)。查询构造器将会添加 where 语句、 order by 和 limit 。
API 与 chunk
彻底相同。只要你不使用任何自定义的 order by 子句,它就是 4 个字符的变化。
返回原文 ↩︎