4

我目前正在使用 PDO 在 PHP 中编写一个 CRUD 类。

我喜欢prepared statements提供的安全性,但我听说它们也阻止了mysql等数据库使用queryCache。

当您一次只做一个选择时,使用准备好的 Select 语句会更好吗?或者只是 $pdo->quote() 从安全角度来看就足够了(或者有任何其他优势,比如缓存?)。

我所有的更新、删除和插入都是使用准备好的语句完成的。我只是对选择感到好奇。

4

6 回答 6

13

MySQLPerformanceBlog.com 在一篇关于“ Prepared Statements ”的文章中做了一些基准测试。彼得扎伊采夫写道:

我做了一个简单的基准测试(使用 SysBench)来查看使用标准语句、准备好的语句的简单查询(单行点选择)的性能,并从查询缓存中提供服务。Prepared statements 提供 2290 个查询/秒,这明显优于标准语句的 2000 个,但当从查询缓存提供结果时,它仍然远低于 4470 个查询/秒。

这似乎是说使用准备好的语句的“开销”是它们比使用直接查询执行14.5% ,至少在这个简单的测试中是这样。相对差异可能会随着更复杂的查询或更大的结果集而减小。

考虑到服务器的双重往返和其他因素,准备好的查询会更快,这似乎违反直觉。彼得的基准缺乏细节。无论如何,您应该运行自己的测试,因为您运行的查询类型以及您的环境和硬件绝对是重要的因素。

至于查询缓存,过去确实是prepared statements 与缓存查询结果不兼容,但是这已经改变了。请参阅MySQL 文档中的“查询缓存如何操作”:

在 MySQL 5.1.17 之前,prepared statements 不使用查询缓存。从 5.1.17 开始,prepared statements 在某些条件下使用查询缓存,这取决于准备方法: ...

文档继续描述这些条件。去读吧。

我建议使用准备好的语句进行SELECT查询。在将变量插入 SQL 语句时引用变量会很有效,前提是您始终如一地这样做。但即使是引用也可能有一些微妙的安全漏洞,例如多字节字符集(参见 MySQL 错误 # 8378)。在这些情况下,以安全的方式使用准备好的查询会更容易。

于 2009-03-22T23:29:01.477 回答
2

是的,使用准备好的语句。我严重怀疑您是否会遇到性能问题,因为准备好的语句比普通的文字查询运行得慢得多。但是,在 mysql 上,您似乎是正确的。尽管如此,我还是会选择准备好的陈述。

这是一个参考: http ://www.mysqlperformanceblog.com/2006/08/02/mysql-prepared-statements/

虽然,如果你担心缓存,你可能想看看memcached 之类的东西。

于 2009-03-22T23:12:06.543 回答
1

这是我的理解,正如以下讨论所证实的那样:这里

普通查询被视为单个字符串,被解析、执行并返回。故事结局。将准备好的语句作为模板字符串,进行解析和缓存。然后将变量传递给它,就像函数调用一样。

缓存一次查询的成本往往比直接执行要多一点。当您跳过编译步骤时,节省会在以后的调用中出现。您可以为每个重复查询保存编译量。

因此,简而言之,在 MySQL 上,如果您只执行一次查询,准备它只会增加不必要的额外处理量。

于 2009-03-22T23:18:15.217 回答
1

准备好的语句通常被认为是更好的做法。

我建议阅读有关准备好的语句及其实用性和优于传统普通普通插值字符串查询的MySql 文章。

于 2009-03-22T23:20:53.993 回答
1

您是在应用程序生命周期中只选择“一次”,还是每次调用函数“一次”?

因为如果是后者,您仍然应该从准备好的语句中的缓存中受益。

于 2009-03-22T23:26:14.650 回答
0

只是提醒一下 MySQL > 5.1.17确实使用查询缓存来准备语句。

从代码 POV 来看,我相信准备好的语句在很大程度上是可读性、可维护性等方面的方法......

不使用它们的一个原因是会以某种频率调用昂贵的查询。(查询需要花费大量时间才能运行,并且对查询缓存有真正的好处)。

于 2009-03-22T23:27:51.543 回答