Há uma pequena coisa a mencionar. Por padrão, o PDO apenas emula instruções preparadas.
E enquanto estiver no modo de emulação, ele executa a mesma consulta antiga sem realmente preparar uma única instrução :)
Então, em primeiro lugar,
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
para ativar declarações preparadas de verdade.
Há outra coisinha para mencionar.
Infelizmente, há muito pouco reais conhecimento no mundo. E especialmente no mundo dos sites de perguntas e respostas. As pessoas tendem a repetir as informações que leram e acharam razoável. Sem fazer nenhum teste de comprovação ou mesmo sem colocar as mãos. Portanto, "frequentemente observado" não deve ser considerado uma fonte confiável.
Voltando ao assunto:embora deva haver alguma penalidade, deve ser insignificante na maioria das vezes. Se for - você tem que ajustar seu sistema.
De qualquer forma, no modo de emulação, você conseguiu "rápido" e seguro.
Atualizar
Bem, depois de executar seus testes em meus dados, devo dizer que há algo errado com seu banco de dados se você tiver 3 vezes a diferença em um conjunto de dados grande.
Para uma consulta relâmpago
select title from Board where id = 1
os resultados são
emulation on off
query 0.07 0.130
prepare 0.075 0.145
enquanto para a consulta bastante onerosa
select title from Board where id > 1
os resultados são
emulation on off
query 0.96 0.96
prepare 0.96 1.00
Então, como podemos ver, em um grande conjunto de dados a diferença se torna imperceptível.
Para a consulta relâmpago há alguma diferença, mas, como leva apenas 0,0003ª facção de segundo (para uma única consulta) - eu diria que é um exemplo perfeito para a palavra "indiferença".
Para resultados iguais entre query()/prepare() - tenho apenas uma ideia - o PDO usa prepare/execute para todas as consultas, mesmo aquelas sem vinculações.
Agora vamos ao problema de codificação.
Sim, o problema estranho do GBK afeta o PDO para versões anteriores a 5.3.3. Essas versões não tinham como definir a codificação adequada e eram inevitavelmente vulneráveis (no modo de emulação). Mas desde 5.3.3 PDO suporta a configuração de codificação em DSN, e agora está tudo certo com ele.
Para mysqli é preciso usar
mysqli_set_charset()
para este mesmo propósito com o mesmo resultado (impenetrável). Na minha própria classe que é baseada no mysqli, estou usando minha própria implementação de espaço reservado e não uso nenhuma instrução preparada. Não por razões de desempenho, mas para melhor confiabilidade.