ホームページ >バックエンド開発 >PHPチュートリアル >多数のループに PHP を使用する場合のメモリ最適化の例
大量のデータを処理する必要がある場合があります。ループが多すぎるとメモリが枯渇する可能性があります。この問題を解決するにはどうすればよいですか?以下のエディタは、PHP で大量のデータをループするときのメモリ不足の問題を解決するのに役立ちます。必要な友人はそれを参照できます。お役に立てれば幸いです。
最近、PHP プログラムの開発中に次の問題に遭遇しました:
PHP 致命的なエラー: 許容メモリ サイズ 268 435 456 バイトが使い果たされました
エラー メッセージは、最大許容メモリが使い果たされたことを示しています。最初はこのようなエラーが発生したことに驚きましたが、よく考えてみると、私が開発しているプログラムは foreach ループ ステートメントを使用して 40,000 レコードのデータを持つテーブル内の特定の特性を検索することになっているため、驚くべきことではありません。つまり、一度に4万件のデータを取り出し、毎日のデータを一つ一つチェックしなければなりません。 40,000件のデータをすべてメモリにロードした場合、メモリがバーストしなくても不思議ではないと考えられます。
結局、何年もプログラミングをしてきて、PHP が提供する API はデータを一度にロードしないことを漠然と覚えています。これは、ストリーミング メディアやデータと同じように、使用したり失われる可能性のあるクエリ メソッドです。記憶に蓄積されない。簡単に検索したところ、公式Webサイトに正しい使用方法が見つかりました。
この問題は、PHP の公式 Web サイトでは「バッファー付きクエリ」と「バッファーなしクエリ」と呼ばれています。 PHP のデフォルトのクエリ モードはバッファ モードです。つまり、クエリ データの結果は、PHP プログラムによる処理のために一度にメモリに抽出されます。これにより、PHP プログラムに行数のカウント、特定の行へのポインタの指示などの追加機能が与えられます。さらに重要なことは、プログラムがデータ セットに対して二次クエリとフィルタリング操作を繰り返し実行できることです。ただし、このバッファー クエリ モードの欠点は、メモリを消費すること、つまり、速度と引き換えにスペースを消費することです。
対照的に、別の PHP クエリ モードはバッファなしクエリであり、データベース サーバーはデータを一度に返すのではなく 1 つずつ返します。その結果、PHP プログラムが消費するメモリは少なくなりますが、データベースへの負荷は増加します。これは、すべてのデータがフェッチされるまで、データベースが PHP によるデータのフェッチを待機するためです。
明らかに、バッファー クエリ モードは少量のデータ量のクエリに適しており、非バッファー クエリは大量のデータ量のクエリに適しています。
PHP のバッファー モード クエリについては誰もが知っています。以下に示す例は、非バッファー クエリ API を実行する方法です。
非バッファ型クエリ方法 1: mysqli
<?php $mysqli = new mysqli("localhost", "my_user", "my_password", "world"); $uresult = $mysqli->query("SELECT Name FROM City", MYSQLI_USE_RESULT); if ($uresult) { while ($row = $uresult->fetch_assoc()) { echo $row['Name'] . PHP_EOL; } } $uresult->close(); ?>
非バッファ型クエリ方法 2: pdo_mysql
<?php $pdo = new PDO("mysql:host=localhost;dbname=world", 'my_user', 'my_pass'); $pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); $uresult = $pdo->query("SELECT Name FROM City"); if ($uresult) { while ($row = $uresult->fetch(PDO::FETCH_ASSOC)) { echo $row['Name'] . PHP_EOL; } } ?>
非バッファリングクエリ方法 3: mysql
<?php $conn = mysql_connect("localhost", "my_user", "my_pass"); $db = mysql_select_db("world"); $uresult = mysql_unbuffered_query("SELECT Name FROM City"); if ($uresult) { while ($row = mysql_fetch_assoc($uresult)) { echo $row['Name'] . PHP_EOL; } } ?>
関連する推奨事項:
PHP ループ時間制御バッファーメソッド_PHP チュートリアル
PHP ループステートメントの基本構文構造に関するメモ_PHP チュートリアル
以上が多数のループに PHP を使用する場合のメモリ最適化の例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。