在Laravel
中使用cursor
來查詢並處理資料 (輕鬆處理千萬級的資料)
事發現場
最近在專案中遇到記憶體不足的問題, 測試環境中的PHP記憶體只有64M,在匯出的時候, 資料量比較大,這個時候會出現記憶體溢位的錯誤.
如何解決
目前想到兩種方法:
- 調整
php.ini
檔案中memory_limit
配置項; 或者在呼叫方法中調整記憶體大小ini_set('memory_limit', "")
. - 使用
Laravel
的Lazy Collection
.
考慮到修改配置檔案的影響範圍過大, 以及對匯出的實時性要求不是很高, 所以我們選擇了第二種方法.
Lazy Collection
如何使用Lazy Collection
? 很簡單, 將查詢構建器鏈末尾的get()
更改為cursor()
就好了 !
cursor ( )
cursor
的原理cursor
的實現使用了yield
關鍵字,yield
關鍵字是生成器函式的核心, 它的呼叫形式跟return
很像, 不同之處在於return會返回值並且終止函式執行, 而yield
會返回值給迴圈呼叫生成器的程式碼並且只是暫停生成器函式.cursor()
的程式碼如下/** * Get a generator for the given query. * * @return \Generator */ public function cursor() { foreach ($this->applyScopes()->query->cursor() as $record) { yield $this->newModelInstance()->newFromBuilder($record); } }
由於使用了
yield
關鍵字, 在迴圈cursor
生成器的時候,可以漸進式的處理資料,即使在記憶體很小的情況下,也可以輕鬆處理千萬級的資料! 真的是非常方便哦!
本作品採用《CC 協議》,轉載必須註明作者和本文連結