$pdo = new PDO('MysqL:host=localhost;dbname=cwadb_local','root',""); $start = microtime(true); for ($i = 0; $i < 200; $i++) { $pdo->query("select * from person where name_last = 'smith' or true"); } echo "<p>query: " . (microtime(true) - $start); $start = microtime(true); for ($i = 0; $i < 200; $i++) { $stmt = $pdo->prepare("select * from person where name_last = :last or true"); $stmt->execute(array('last' => 'smith')); } echo "<p>prepare/execute: " . (microtime(true) - $start);
这是输出:
query: 21.010436058044 prepare/execute: 20.74036192894
这显示没有任何惩罚.可能性:
>准备好的语句的缓存确实有效. (注意我将prepare函数保留在循环中.)
>这是一个虚假的测试,因为它太简单了.
>没有理论上的原因,为什么准备/执行应该更慢,并且厌倦了不断的批评,MysqL / PDO / PHP开发人员更加努力地使它们更快,以试图让我们所有人闭嘴.
>其他?
这里有很多次说使用预处理语句比使用查询更安全,并且在PDO中使用命名参数(MysqLi没有它们),处理参数非常方便.但是,正如经常指出的那样,如果必须在每次执行时都准备好语句,那么就会有性能损失.
那么,有人可以提供一些与我的简单测试相矛盾的测试吗?或者,我们现在是否承认没有理由不使用准备好的陈述?
而在仿真模式下,它运行相同的旧查询而不实际准备单个语句:)
所以,首先,
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,FALSE);
准备好真实的准备陈述.
it’s just as often noted that there’s a performance penalty
还有一件事要提.
可悲的是,世界上几乎没有真正的知识.特别是在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
因此,正如我们所看到的,在大型数据集上,差异变得不明显.
对于闪电查询存在一些差异,但是,因为它只需要第二万分之一(对于单个查询) – 我会说这是“无差异”一词的完美示例.
对于query()/ prepare()之间的相同结果 – 我只有一个想法 – PDO对所有查询使用prepare / execute,即使是那些没有绑定的查询.
现在来编码问题.
是的,奇怪的GBK问题确实影响了5.3.3之前版本的PDO.这些版本无法设置正确的编码,并且不可避免地容易受到攻击(在仿真模式下).但是由于5.3.3 PDO支持在DSN中设置编码,现在一切都很好.
对于MysqLi,必须使用MysqLi_set_charset()来达到这个目的,并使用相同的(不可穿透的)结果.