[Osaka/Yokohama] Looking for infrastructure/server side engineers!

[Osaka/Yokohama] Looking for infrastructure/server side engineers!

[Deployed by over 500 companies] AWS construction, operation, maintenance, and monitoring services

[Deployed by over 500 companies] AWS construction, operation, maintenance, and monitoring services

[Successor to CentOS] AlmaLinux OS server construction/migration service

[Successor to CentOS] AlmaLinux OS server construction/migration service

[For WordPress only] Cloud server “Web Speed”

[For WordPress only] Cloud server “Web Speed”

[Cheap] Website security automatic diagnosis “Quick Scanner”

[Cheap] Website security automatic diagnosis “Quick Scanner”

[Reservation system development] EDISONE customization development service

[Reservation system development] EDISONE customization development service

[Registration of 100 URLs is 0 yen] Website monitoring service “Appmill”

[Registration of 100 URLs is 0 yen] Website monitoring service “Appmill”

[Compatible with over 200 countries] Global eSIM “Beyond SIM”

[Compatible with over 200 countries] Global eSIM “Beyond SIM”

[If you are traveling, business trip, or stationed in China] Chinese SIM service “Choco SIM”

[If you are traveling, business trip, or stationed in China] Chinese SIM service “Choco SIM”

[Global exclusive service] Beyond's MSP in North America and China

[Global exclusive service] Beyond's MSP in North America and China

[YouTube] Beyond official channel “Biyomaru Channel”

[YouTube] Beyond official channel “Biyomaru Channel”

CakePHPで大量のデータをfind(‘all’)したらメモリが足りなくなった【やってみたけど…編】

開発チームの長谷です。

この間試しに、
CakePHPで10万件近くあるデータをfind(‘all’)で取得しようとしたらメモリが足りなくなって、
以下のエラーが出てしまいました。。

Allowed memory size of 134217728 bytes exhausted

そこで、メモリを抑えて10万行近くのデータを取ってこれるようにする方法を色々と調べてみました。

現在のコード

$data = $this->Model->find('all');

// 何らかの処理
.........

query()を使用する

query()で取得する方がfind(‘all’)で取得するよりも処理が軽くなるらしいです。
なので、findで取得してきていたものをquery()で取得するように修正。

$data = $this->Model->query("SELECT * FROM hogehoge;");

// 何らかの処理
.........

結果

気持ち処理が軽くなった気がしましたが、
find('all')して取得した時と変わらず、メモリが足らずエラーが出てしまいました。

query() のキャッシュを無効にする

公式を見たところ、query()にはデフォルトでクエリをキャッシュする仕組みになっているようです。
このクエリをキャッシュするのを無効にするためには、query($query, $cachequeries = false)
というように第2引数に false を指定することで無効にすることができます。
てことで、query() の第2引数に false を指定してみました。

$data = $this->Model->query("SELECT * FROM hogehoge;", $cachequeries = false);

// 何らかの処理
.........

結果

結論としては特に変化はありませんでした。。

ループを使ってデータを分割しながら取得する

そもそも上の方法だと、10万件のデータを一気に取得していることには変わりがないので、
メモリが足らなくなるのは当然でした。
ということでlimit,offsetを駆使してループ処理でデータを分割して取得するようにしてみました。

// データの件数を取得する
$count = $this->Model->find('count');

// 5000件ずつデータを取得するようにする
$limit = 5000;

// ループする回数({データ件数 ÷ 1回の取得件数}の端数を切り上げた数)
$loop  = ceil($count / $limit);

for ($i = 0; $i < $loop; $i++){
	// オフセット
	$offset = $limit * $i;
	
	$data = $this->Model->query("select * from hogehoge as limit {$limit} offset {$offset};", $cachequeries = false);
	
	// 何らかの処理
	.........

}

結果

素晴らしい結果となりました。
メモリエラーも出ず、データもちゃんと取得できていましたのでこれで問題ないですね!!

てことで、もし同じ現象で困っている方がいらっしゃいましたら参考にしていただければ幸いです。

以上です。

しかし、この方法では…
続きはこちらをご覧ください。
CakePHPで大量のデータをfind(‘all’)したらメモリが足りなくなった【解決】 | 株式会社ビヨンド

この記事がお役に立てば【 いいね 】のご協力をお願いいたします!
1
読み込み中...
1 票, 平均: 1.00 / 11
7,111
X facebook はてなブックマーク pocket
[2024.6.30 CentOS support ended] CentOS server migration solution

[2024.6.30 CentOS support ended] CentOS server migration solution

[2025.6.30 Amazon Linux 2 support ended] Amazon Linux server migration solution

[2025.6.30 Amazon Linux 2 support ended] Amazon Linux server migration solution

[Osaka/Yokohama] Actively recruiting infrastructure engineers and server side engineers!

[Osaka/Yokohama] Actively recruiting infrastructure engineers and server side engineers!

The person who wrote this article

About the author

Tatsuya Hase

Joined Beyond Co., Ltd. as a new graduate.

We develop web systems (development of services and systems that run on browsers, such as web services, digital content, and business management systems) and game APIs (development of programs that communicate with application games).

We also develop private/custom apps for Shopify.

Originally worked at the Osaka office, but transferred to the Yokohama office in 2019.
His hobbies are baseball/karaoke/anime