Mar*_*ind 7 php mysql pdo prepared-statement
这是一个简单的测试,我试图快速了解使用MySQL PDO预处理语句与使用直接查询所支付的性能损失.人员表中有2801行.MySQL版本5.5.28和PHP版本5.3.15.香草装置,无论默认参数如何.测试在8GB的iMac上运行.
$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);
Run Code Online (Sandbox Code Playgroud)
这是输出:
query: 21.010436058044
prepare/execute: 20.74036192894
Run Code Online (Sandbox Code Playgroud)
这显示没有任何惩罚.可能性:
缓存准备好的语句确实有效.(注意我将prepare函数保留在循环中.)
这是一个虚假的测试,因为它太简单了.
没有理论上的原因,为什么准备/执行应该更慢,并且厌倦了不断的批评,MySQL/PDO/PHP开发人员已经加倍努力使它们更快,以试图让我们所有人闭嘴.
其他?
这里有很多次说使用预处理语句比使用查询更安全,并且在PDO中使用命名参数(Mysqli没有它们),处理参数非常方便.但是,正如经常指出的那样,如果必须在每次执行时都准备好语句,那么就会有性能损失.
那么,有人可以提供一些与我的简单测试相矛盾的测试吗?或者,我们现在是否承认没有理由不使用准备好的陈述?
You*_*nse 10
有一点要提一点.默认情况下,PDO只是模拟预准备语句.
而在仿真模式下,它运行相同的旧查询而不实际准备单个语句:)
所以,首先,
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
Run Code Online (Sandbox Code Playgroud)
准备好真实的准备陈述.
它经常被注意到会有性能损失
还有一件事要提.
可悲的是,世界上几乎没有真正的知识.特别是在Q&A网站的世界.人们倾向于重复他们阅读过的信息,并认为合理.没有进行任何测试来证明甚至没有亲自动手.因此,"经常注意到"不应被视为可靠的来源.
回到这个问题:尽管应该有一些惩罚,但大部分时间都应该是微不足道的.如果是 - 您必须调整系统.
无论如何,在仿真模式下,你既"快速又安全".
更新
好了,在对我的数据运行测试之后,如果你在大型数据集上有3倍的差异,我必须说你的数据库有问题.
对于闪电查询
select title from Board where id = 1
Run Code Online (Sandbox Code Playgroud)
结果是
emulation on off
query 0.07 0.130
prepare 0.075 0.145
Run Code Online (Sandbox Code Playgroud)
而对于相当繁琐的查询
select title from Board where id > 1
Run Code Online (Sandbox Code Playgroud)
结果是
emulation on off
query 0.96 0.96
prepare 0.96 1.00
Run Code Online (Sandbox Code Playgroud)
因此,正如我们所看到的,在大型数据集上,差异变得不明显.
对于闪电查询存在一些差异,但是,因为它只需要第二个第(000)个派系(对于单个查询) - 我会说这是"无差异"一词的完美示例.
对于query()/ prepare()之间的相同结果 - 我只有一个想法 - PDO对所有查询使用prepare/execute,即使是那些没有绑定的查询.
现在来编码问题.
是的,奇怪的GBK问题确实会影响5.3.3之前版本的PDO.这些版本无法设置正确的编码,并且不可避免地容易受到攻击(在仿真模式下).但是因为5.3.3 PDO支持在DSN中设置编码,现在一切都很好.
对于mysqli,必须使用mysqli_set_charset()相同(不可穿透)的结果来实现此目的.
在我自己的基于mysqli的类中,我使用自己的占位符实现并且根本不使用预处理语句.不是出于性能原因而是为了更好的可靠性
我对你的方法有一些疑问:
time,即:time php myscript.php但是,在非静态查询的情况下,仍然没有理由不使用准备好的语句,除非您喜欢始终严格验证所有输入并且仍然存在 SQL 注入的可能性。
| 归档时间: |
|
| 查看次数: |
3925 次 |
| 最近记录: |