PHP クエリ MySQL メモリ内の大量のデータ

WBOY
リリース: 2016-06-21 08:51:54
オリジナル
921 人が閲覧しました

この記事では主に、PHP で MySQL にクエリを実行して多数の結果を返すときのメモリ使用量の問題について説明し、MySQL C API の使用についても説明します。

昨日、同僚が PHP ディスカッション グループで、彼が取り組んでいるプロジェクトが MySQL クエリから多すぎる結果 (最大 100,000) を返し、その結果 PHP メモリが不足したと述べました。 そこで彼は、返された MySQL の結果を反復処理する次のコードを実行する前に、データがすでにメモリ内にあるのか、と尋ねました。

while ($row = mysql_fetch_assoc($result)) {

//…

}

もちろん、この問題には多くの最適化方法があります。 ただし、この問題に関して私が最初に考えたのは、MySQL は古典的な C/S (クライアント/サーバー、クライアント/サーバー) モデルであり、結果セットをスキャンする前に、基盤となる実装がネットワーク経由ですべてのデータを送信している可能性があるということです (前提として)。 TCP/IP) を使用してクライアントのバッファを読み取る場合、別の可能性があります。つまり、データがまだサーバーの送信バッファ内にあり、クライアントに渡されていないということです。

PHP と MySQL のソース コードを見る前に、PHP マニュアルに同様の機能を持つ 2 つの関数があることに気付きました。

mysql_query()

mysql_unbuffered_query()

2 つの関数の文字通りの意味と説明により、前者の関数が実行されると、すべての結果セットがサーバーからクライアントのバッファーに読み取られますが、後者の関数は「バッファリングされない」ことを意味します。

つまり、mysql_unbuffered_query() を使用して大きな結果セットを返す SQL ステートメントを実行する場合、結果を走査する前に PHP のメモリが結果セットによって占有されることはありません。 mysql_query() を使用して同じステートメントを実行すると、関数が戻るときに PHP のメモリ使用量が急激に増加し、すぐにメモリが消費されてしまいます。

PHP の関連コードを読むと、これら 2 つの関数の実装の類似点と相違点がわかります。

/* {{{ proto resource mysql_query(string query [, int link_identifier])

SQL クエリを MySQL に送信します */

PHP_FUNCTION(mysql_query)

{

php_mysql_do_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_STORE_RESULT);

}

/* }}} */

/* {{{ proto resource mysql_unbuffered_query(string query [, int link_identifier])

結果行のフェッチやバッファリングを行わずに、SQL クエリを MySQL に送信します */

PHP_FUNCTION(mysql_unbuffered_query)

{

php_mysql_do_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_USE_RESULT);

}

/* }}} */

どちらの関数も php_mysql_do_query() を呼び出しますが、2 番目のパラメーター MYSQL_STORE_RESULT と MYSQL_USE_RESULT だけが異なります。 php_mysql_do_query() の実装を見てみましょう。

if(use_store == MYSQL_USE_RESULT) {

mysql_result=mysql_use_result(&mysql->conn);

} else {

mysql_result=mysql_store_result(&mysql->conn);

}

Mysql_use_result() と mysql_store_result() は MySQL の C API 関数です。これら 2 つの C API 関数の違いは、後者は結果セット全体を MySQL サーバーからクライアントに読み取るのに対し、前者は結果のメタ情報のみを読み取ることです。セット。

PHP に戻り、mysql_unbuffered_query() を使用して即時のメモリ占有を回避します。 走査プロセス中に結果が「PHP キャッシュ」されない場合 (結果を配列に配置する場合など)、実行プロセス全体が 10 万または 100 万以上のデータを処理するにもかかわらず、PHP が占有するメモリは常に非常に小さい。



関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のおすすめ
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!