Należy wspomnieć o jednej małej rzeczy. Domyślnie PDO po prostu emuluje przygotowanych instrukcji.
A w trybie emulacji uruchamia to samo stare zapytanie bez przygotowywania ani jednej instrukcji :)
A więc przede wszystkim
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
aby włączyć prawdziwe przygotowane oświadczenia.
Jest jeszcze jedna mała rzecz, o której warto wspomnieć.
Niestety jest bardzo niewiele prawdziwych wiedza na świecie. A zwłaszcza w świecie witryn z pytaniami i odpowiedziami. Ludzie mają tendencję do powtarzania informacji, które przeczytali i uznali za rozsądne. Bez przeprowadzania jakichkolwiek testów w celu sprawdzenia, a nawet bez nakładania rąk. Tak więc „często zauważane” nie powinno być w ogóle uważane za wiarygodne źródło.
Wracając do sprawy:choć powinna być jakaś kara, przez większość czasu powinna być ona nieznaczna. Jeśli tak - musisz dostroić swój system.
W każdym razie w trybie emulacji masz to zarówno „szybko”, jak i bezpiecznie.
Aktualizacja
Cóż, po przeprowadzeniu testów na moich danych, muszę powiedzieć, że coś jest nie tak z Twoją bazą danych, jeśli masz 3-krotną różnicę na dużym zbiorze danych.
W przypadku błyskawicznego zapytania
select title from Board where id = 1
wyniki są
emulation on off
query 0.07 0.130
prepare 0.075 0.145
natomiast dla dość uciążliwego zapytania
select title from Board where id > 1
wyniki są
emulation on off
query 0.96 0.96
prepare 0.96 1.00
Tak więc, jak widzimy, na dużym zbiorze danych różnica staje się niezauważalna.
W przypadku zapytania lightning jest pewna różnica, ale ponieważ zajmuje to tylko 0,0003 frakcji sekundy (dla pojedynczego zapytania) - powiedziałbym, że to doskonały przykład dla słowa "obojętność".
Dla równych wyników między query()/prepare() - mam tylko jeden pomysł - PDO używa metody read/execute dla wszystkich zapytań, nawet tych bez powiązań.
Teraz przejdźmy do problemu z kodowaniem.
Tak, dziwny problem GBK wpływa na PDO dla wersji wcześniejszych niż 5.3.3. Wersje te nie miały możliwości ustawienia właściwego kodowania i były nieuniknione podatne na ataki (w trybie emulacji). Ale od wersji 5.3.3 PDO obsługuje ustawianie kodowania w DSN i teraz wszystko jest z nim w porządku.
Dla mysqli trzeba użyć mysqli_set_charset()
w tym celu z takim samym (nieprzeniknionym) rezultatem.
W mojej własnej klasie opartej na mysqli używam własnej implementacji zastępczej i nie używam w ogóle żadnych przygotowanych instrukcji. Nie ze względu na wydajność, ale dla większej niezawodności.