PHP が MySQL に大量のデータをクエリするときのメモリ使用量の分析

WBOY
リリース: 2016-06-13 12:07:04
オリジナル
1269 人が閲覧しました

昨日、同僚が 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 ステートメントを実行する場合です。 set の場合、結果をトラバースする前に 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_FU NCTION_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 関数全体を読み取ることです。結果セットは MySQL サーバーからクライアントに送信されますが、前者は結果セットのメタ情報を読み取るだけです。

PHP では、結果が「 「PHP キャッシュ」がトラバーサル プロセス (配列への配置など) 中に実行されると、実行プロセス全体が数十万または数百万のアイテムやデータを処理しますが、PHP のメモリ フットプリントは常に非常に小さいです。
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のおすすめ
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート