讓 Laravel Scout 導入提速 64 倍

文章轉發自專業的Laravel開發者社區,原始鏈接:https://learnku.com/laravel/t...

下一個版本的 Laravel Scout 將會使你的模型查詢速度提升64倍。

我使用null scout 驅動測試了一張包含 1,632,576條數據的表。消耗的時間從過去的29分57秒縮短到了28秒。 1^](https://mattallan.me/posts/ma...:1)

你能在這裏 查看提交的 pull request.

這篇文章解釋了爲什麼代碼中的這個更改會帶來這麼大的變化。這是我在我自己的 Laravel 應用中用來加速存在問題的查詢的一個技巧。一旦你理解了它的原理,我打賭你會找到一種新的優化你的應用的方式。

背景

默認情況下, Scout 會檢索數據庫中的每一行。爲了保持內存使用的合理性,它使用 chunk 方法 一次只取幾百行。

chunk 方法爲你的查詢添加了限制和偏移量,像這樣:

select * from `users` order by `id` asc limit 500 offset 500;

要獲取下一頁,偏移量會遞增。

select * from `users` order by `id` asc limit 500 offset 1000;

首先這很好用,這個查詢大約只需要大約一毫秒,但你走的越遠,它就越慢。

一旦偏移量達到了 1,000,000 ,查詢速度就會很容易慢 500 倍。當 Scout 導入執行數千個這樣的查詢時,它會累加起來。

爲什麼偏移量速度慢

當你使用偏移量時,你是在告訴數據庫要跳過前 N 行。即使沒有返回跳過的這些行,數據庫仍然會從磁盤讀取它們並對它們進行排序。

數據庫 可能 能夠使用索引並避免獲取整個行。我們的示例查詢中使用主鍵索引,但仍然可以抓取。

使 ChunkById 更快的分塊

事實證明,不使用偏移量就可以很容易地對結果進行分頁。我們所要做的就是跟蹤我們看到的最後一個 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 個字符的變化。


  1. [返回原文
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章