プリペアドステートメントにはパフォーマンスの利点(同じクエリを何度も発行するときにDBサーバーがクエリの解析を繰り返さないでもすむ)というものと、SQLインジェクション対策になる(正しくSQLを実行できる)という利点がありますが、特にPHPではWebアクセスの度にプリペアし直すのでパフォーマンスの利点は殆ど無くて、基本的には正しくSQLを実行するために使ってることが多いのではないでしょうか?
変数を含むSQLを正しく実行するのに、別にプリペアドステートメントを使う必要はありません。変数の値を、正しくエスケープ処理して、SQLに埋め込めば良いのです。そして、 PDO::ATTR_EMULATED_PREPARE を利用すると、PDOのプリペアドステートメントを普通に使うだけで、PDO内部で正しくエスケープされたSQLを構築してMySQLに投げてくれるので、クエリ実行時に発行するコマンドが1つですむようになり、DBサーバーのCPU,ネットワーク帯域、パケット数を全て削減できます。この設定をするには、PDOのオブジェクトに対して次の1行を実行するだけです。
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
DSAS開発者の部屋:MySQL を PDO で使うときは ATTR_EMULATE_PREPARES を設定しよう
注意しないといけない点として、この設定を使うと一部挙動が変わる可能性があります。たとえば、 “…LIMIT ?” というクエリに ->execute(array(…, 3)); とすると、 “…LIMIT ‘3’” (シングルクォートに注目) に展開されてしまってSQLが不正になってしまうので、型を指定して bindParam() を利用するなり、整数型と判っている部分だけ通常の ($limit が正の整数として “…LIMIT $limit” のような) 文字列処理をする必要があります。
