言及すべき小さなことが1つあります。デフォルトでは、PDOはエミュレートするだけです プリペアドステートメント。
そして、エミュレーションモードでは、実際に1つのステートメントを準備することなく、同じ古いクエリを実行します:)
それで、まず第一に、
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
実際に準備されたステートメントをオンにします。
もう1つ言及すべきことがあります。
残念ながら、実際のはほとんどありません。 世界の知識。特にQ&Aサイトの世界では。人々は、読んで妥当だと思った情報を繰り返す傾向があります。証明するためのテストを実行せずに、あるいは手を置くことなく。したがって、「よく知られている」とは、信頼できる情報源とはまったく見なされるべきではありません。
問題に戻ります。ある程度のペナルティがあるはずですが、ほとんどの場合、それは重要ではないはずです。もしそうなら-あなたはあなたのシステムを調整しなければなりません。
とにかく、エミュレーションモードでは、「高速」で安全です。
更新
そうですね、私のデータでテストを実行した後、大きなデータセットで3倍の違いがある場合は、データベースに問題があると言わざるを得ません。
稲妻クエリの場合
select title from Board where id = 1
結果は
emulation on off
query 0.07 0.130
prepare 0.075 0.145
非常に面倒なクエリの場合
select title from Board where id > 1
結果は
emulation on off
query 0.96 0.96
prepare 0.96 1.00
したがって、ご覧のとおり、大規模なデータセットでは違いが目立たなくなります。
稲妻のクエリにはいくつかの違いがありますが、(単一のクエリの場合)2番目の派閥が0,0003しかないため、これは「無関心」という言葉の完璧な例だと思います。
query()/ prepare()の結果を等しくするには、アイデアは1つだけです。PDOは、バインディングのないクエリも含め、すべてのクエリにprepare/executeを使用します。
エンコードの問題について説明します。
はい、奇妙なGBKの問題は、5.3.3より前のバージョンのPDOに影響します。これらのバージョンには適切なエンコーディングを設定する方法がなく、(エミュレーションモードで)避けられない脆弱性がありました。ただし、5.3.3以降、PDOはDSNでのエンコーディングの設定をサポートしており、今ではすべて問題ありません。
mysqliの場合、mysqli_set_charset()
を使用する必要があります。 この目的のために、まったく同じ(不可解な)結果が得られます。
mysqliに基づく私自身のクラスでは、私自身のプレースホルダー実装を使用しており、プリペアドステートメントをまったく使用していません。パフォーマンス上の理由ではなく、信頼性を高めるためです。