Laravel慢查詢優(yōu)化:使用fast-paginate加速分頁

在使用 laravel 開發(fā)包含大量數(shù)據(jù)的應(yīng)用時,分頁是一個常見的需求。然而,當數(shù)據(jù)量達到數(shù)十萬甚至數(shù)百萬級別時,傳統(tǒng)的 paginate() 方法由于其底層的 offset 和 limit 實現(xiàn)方式,可能會導(dǎo)致查詢速度急劇下降,嚴重影響用戶體驗。

我之前就遇到了類似的問題。一個包含大量用戶數(shù)據(jù)的管理后臺,在進行分頁查詢時,響應(yīng)時間竟然高達幾十秒,這簡直無法接受。經(jīng)過一番研究,我發(fā)現(xiàn)了 aaronfrancis/fast-paginate 這個 laravel 包,它通過一種稱為“延遲連接”(deferred join)的 sql 技術(shù),極大地優(yōu)化了分頁查詢的性能。

composer在線學(xué)習(xí)地址:學(xué)習(xí)地址

延遲連接的原理

fast-paginate 的核心思想是延遲對數(shù)據(jù)的訪問,直到應(yīng)用了 offset 和 limit 之后。它通過創(chuàng)建一個子查詢,該子查詢僅獲取需要分頁的 ID,然后再使用這些 ID 從主表中檢索完整的行數(shù)據(jù)。

用 SQL 語句來表示,大概是這樣的:

select * from contacts              -- 你想要展示給用戶的完整數(shù)據(jù)     where contacts.id in (          -- "延遲連接" 或子查詢         select id from contacts     -- 分頁,只訪問盡可能少的數(shù)據(jù) - 僅 ID         limit 15 offset 150000     )

然而,由于 mysql 的限制,fast-paginate 實際上會將這個查詢拆分成兩個獨立的查詢來執(zhí)行,以避免 LIMIT & IN/ALL/ANY/SOME subquery 錯誤。

安裝與使用

安裝 fast-paginate 非常簡單,只需通過 Composer 引入即可:

composer require aaronfrancis/fast-paginate

安裝完成后,就可以直接在任何使用 Model::query()->paginate() 的地方,替換為 Model::query()->fastPaginate(),方法簽名完全相同,無需修改其他代碼。

例如:

use AppModelsUser;  $users = User::query()->fastPaginate(15); // 每頁顯示 15 個用戶

甚至可以用于關(guān)聯(lián)關(guān)系的分頁:

$posts = User::first()->posts()->fastPaginate(10); // 獲取第一個用戶的 10 篇文章

實際效果

在使用 fast-paginate 后,我的管理后臺分頁查詢速度得到了顯著提升。原本需要幾十秒的查詢,現(xiàn)在只需要幾百毫秒,用戶體驗得到了極大的改善。

根據(jù)社區(qū)反饋,fast-paginate 的性能提升非常明顯:

  • 30 秒 –> 250 毫秒
  • 28 秒 –> 2 秒
  • 7.5 倍加速
  • 1.1 秒 –> 0.1 秒
  • 20 秒 –> 2 秒
  • 2 秒 –> 0.2 秒

總結(jié)

aaronfrancis/fast-paginate 是一個簡單而強大的 Laravel 包,可以有效解決大數(shù)據(jù)量下的分頁慢查詢問題。它通過延遲連接的 SQL 技術(shù),優(yōu)化了查詢性能,提升了用戶體驗。如果你正在 Laravel 項目中遇到分頁性能瓶頸,不妨嘗試一下 fast-paginate,相信它會給你帶來驚喜。

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點贊8 分享