11

PDOで準備されたステートメントは、使用後に解放する必要がありますか?もしそうなら、どのように?DEALLOCATE PREPARE具体的には、MySQLについて質問しています。PDOを介してどのように電話をかけることができますか。(編集:明確にするために、この質問はエミュレートされた準備ではなく、実際の準備を指します。)

また、これにより結果セットが解放されますか(大きい場合)?

説明:

私はの行に沿ってコードを見てきました

$stmnt = $db->prepare($sql);
$stmnt->execute($aParams);
$stmnt = null;

これは、これが何をするのか、いつ、そしてfunset($stmnt);が異なるのかどうか疑問に思いましたか?

マニュアルはそれを示しています

クエリが準備されると、データベースはクエリを実行するための計画を分析、コンパイル、および最適化します。[...]プリペアドステートメントを使用することにより、アプリケーションは分析/コンパイル/最適化のサイクルを繰り返さないようにします。

これは、ステートメントの割り当てを解除する必要があることを示唆する傾向があり、MySQLには機能があります。それで、

  1. 電話できますDEALLOCATE PREPAREか、そしてどのように
  2. あなたはそれをすべきですか?
  3. そして、ステートメントをnullに設定する(またはステートメントを設定解除する)と、mysql_およびmysqli_の「free_result」と同じようになることを誰かが確認できますか?
  4. それはすぐに起こりますか、それともガベージコレクターが起動するのを待ちますか?

完全を期すために、の「free_result」および「close」関数を参照する別のSO質問mysqli_()は、ステートメントを解放すると実際に時間が追加されることを示唆しています(メモリ使用量が多く、スペースが必要な場合を除く)。ただし、「free_result」は、SQLサーバーを解放して準備されたステートメントをキャッシュすることとは異なります。

4

2 に答える 2

4

PDOで準備されたステートメントは、使用後に解放する必要がありますか?もしそうなら、どのように?

MySQLのコンテキストでは?いいえ、なぜですか?

PDOは、デフォルトでプリペアドステートメントをエミュレートします。これは、PDO自体がパラメーターの置換やエスケープなどを行い、ネイティブのプリペアドステートメントを使用する代わりにSQLのチャンクを送信することを意味します。

オンにすることはできますが、バッファリングされていないクエリも使用している場合を除いて、ハンドルを明示的に閉じる必要はありません。ステートメントハンドルをスコープ外にするか、nullに設定するだけでは、カーソルは閉じません。繰り返しますが、これはバッファリングされていないクエリを使用している場合にのみ重要です。そうでない場合は、スコープから外すか、nullに設定するだけで、ハンドルをきれいに閉じることができます。

また、にリンクしましたDEALLOCATE PREPARE。この構文は、SQL文字列を使用して手動で呼び出す場合にのみ必要です。これは、使用しているMySQLCレベルのAPIベースのプリペアドステートメントとは完全に別個のアクションです。(さて、あなたは多分あなたが使っているかもしれません、しかしそれは事実上同じものです。)PREPAREPDO_MYSQLmysqlnd

于 2012-12-08T06:50:09.107 に答える
1

はい。prepareステートメントが完了したら、それをに設定するNULLか、を使用できますunset()

複数のクエリと大規模なデータベースを持つスクリプトの場合、これは違いを生みます。次の方法でテストできます。

$before = memory_get_usage();
$stmt = NULL;
die(memory_get_usage() - $before);

私にとって、これは20MBのメモリを節約し、後でスクリプトをクラッシュさせていました。

于 2016-05-18T17:07:49.887 に答える