2

現在、準備されたステートメントをプライベート変数に保存しています。これは、準備されたステートメントが深層で実際にどのように機能するかを無視し、念のため実行するためです。

したがって、質問は非常に簡単です。同じ を反復処理すると$PDO->prepare()、同じクエリが再び準備されますか?

foreach( $arr as $docid ) {
  if( $this->dbLink === null ) { // PDO resource, saved in the object.
     throw new Exception( 'Must first connect to DB' );
  }
  if( $this->queryCheckAccess === null ) {
    $query = 'SELECT * from something where id = :id';
    $this->queryCheckAccess = $this->dbLink->prepare($query);
  }
  else {
    $result = $this->queryCheckAccess->execute(array(':id'=>$docid));
  }
}

それは問題になりますか?それとも、DB エンジン / PHP は、それが同じ準備済みステートメントであることを認識できるほどスマートなのでしょうか?

どうもありがとう。

- - - - - - - - - 編集 - - - - - - -

誤解されていたと思います。

私が尋ねるのは、私がそうするとどうなるかということです:

$query = 'SELECT * from something where id = :id';
$this->queryCheckAccess = $this->dbLink->prepare($query);
$query = 'SELECT * from something where id = :id';
$this->queryCheckAccess = $this->dbLink->prepare($query);
$query = 'SELECT * from something where id = :id';
$this->queryCheckAccess = $this->dbLink->prepare($query);
$query = 'SELECT * from something where id = :id';
$this->queryCheckAccess = $this->dbLink->prepare($query);

そして、私が行うとどうなりますか:

if( $this->queryCheckAccess === null ) {
  $query = 'SELECT * from something where id = :id';
  $this->queryCheckAccess = $this->dbLink->prepare($query);
}

エンジンは、最初の例でクエリを 4 回準備しますか? または、それが同じクエリであり、それを「ジャンプ」するだけであることに気付くでしょうか?

4

4 に答える 4

0

あなたの例に似たコードを実行し、MySQLクエリログを有効にしました すべての準備要求がMySQLサーバーに送信されることがわかりました

   Prepare  SELECT * FROM test_table WHERE username = ?
   Close stmt   
   Prepare  SELECT * FROM test_table WHERE username = ?
   Close stmt   
   Prepare  SELECT * FROM test_table WHERE username = ?
   Close stmt   
   Prepare  SELECT * FROM test_table WHERE username = ?
   Close stmt

テストコード:

$sth = $dbh->prepare($sql);
$sth = $dbh->prepare($sql);
$sth = $dbh->prepare($sql);
$sth = $dbh->prepare($sql);
$sth = $dbh->prepare($sql);
$sth->bindParam(1, $user);
$sth->execute();

次に、最善の方法は、一度準備して、異なる値をバインドしてから実行することです。

$sth = $dbh->prepare($sql);
$user = "test";
$sth->bindParam(1, $user);
$sth->execute();

$user = "test2";
$sth->bindParam(1, $user);
$sth->execute();

$user = "test";
$sth->bindParam(1, $user);
$sth->execute();
于 2013-09-25T20:53:31.730 に答える
-1

いいえ、それはプリペアド ステートメントの主な機能の 1 つです。異なる変数を使用して同じクエリを複数回実行する場合は、クエリを準備すると速度が向上します。特にトランザクションを利用する場合 (InnoDB ストレージ エンジンが必要)。

于 2013-09-25T20:21:39.550 に答える
-1
  • タイトルからの質問 (本文の質問とはかなり異なります) に答えるには、同じステートメントを複数回準備することを避ける最善の方法は、明らかに、複数の同様のクエリをまったく実行しないことです。

  • 質問本文からの質問に答えるために-いいえ、DBエンジン/ PHPは、同じクエリが再度用意されたことを知るほど「スマート」ではありません。新しい prepare() 呼び出しごとに、別のステートメントが作成されます。そして、私はそのような「賢い」行動を最初に嫌います. ツールが「賢く」なればなるほど、予測不可能な結果が得られます。

  • コードの実際の問題に答えるために、賢い開発者は適切なツールを使用してトラブルを回避します。
    safeMysqlを使用すると、混乱全体が 1 つのクエリと 1 行のコードに削減されます

    $data = $this->dbLink->getAll('SELECT * from somth where id IN (?a)', $arr);
    

    S0 - 複数のクエリ、複数の準備、複数の質問はありません。

ところで、コードで最初の id を失っています。それでも、結果を適切に使用しないと、最後の 1 つを除いてすべてを失うことになります。

于 2013-09-26T06:14:17.663 に答える