prepare与sql的开销?

请教相同的SQL查询语句用prepare与query的开销是一样大的吗?
$sql = $pdo -> prepare("select * from table");
$sql -> execute();
$rs = $sql -> fetch(PDO :: FETCH_ASSOC);

$sql = $pdo -> query("select * from table");
$rs = $go -> fetch(PDO :: FETCH_ASSOC);
例如上面prepare与query查询是否效率一样?(忽略SQL语句注入)。
单条查询结果用哪一条比较好?
prepare是否在查询时会向数据库至少发送两次数据库?

关于PDO的prepare是否只适合于select?其他的update、insert into这两个操作呢?prepare用占位符可以有效防注入,但当?="abc./-+#$%`123"这些特殊符号(除非对其转义)时,执行语句却报错,
exec是否更适用于update、insert into?

阅读 4.1k
2 个回答

PHP 的 PDO里面有个选项,叫 ATTR_EMULATE_PREPARES

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

正式的prepare需要把这个设置成false。

prepare支持所有DML语句。 清单在此 https://dev.mysql.com/doc/ref... 几乎涵盖了所有日常能用到的语句

正式的prepare 需要和数据库服务器通信两次,一次prepare,一次“填空”。
query和exec只需要一次。

所以看起来prepare会慢。

但是prepare 之后,“填空”的速度是优化过的,格外快。

所以结论是,如果SQL服务器在本地,prepare和query在执行一次的时候几乎是速度一样的。
如果需要插入100次数据,需要prepare一次,“填空”100次,同等条件下(SQL服务器网络延迟相同),prepare的速度远远优于一条一条query执行。
如果客户端和SQL服务器距离差半个地球,那么query可能更快。

所以尽量统统用prepare吧,没毛病。一个是增加效率,一个是放注入。注入大部分都是发生在update 和insert上,结果这俩你想用exec,那还防个毛线。。。

你的“执行语句却报错”是你自己的问题,不信的话你把你相关PDO的代码和SQL错误代码贴出来。

新手上路,请多包涵

1.PDO::query执行一条SQL语句,如果通过,则返回一个PDOStatement对象。PDO::query函数有个“非常好处”,就是可以直接遍历这个返回的记录集。
2.PDO::exec执行一条SQL语句,并返回受影响的行数。此函数不会返回结果集合。官方建议:
对于在程序中只需要发出一次的 SELECT 语句,可以考虑使用 PDO::query()。
对于需要发出多次的语句,可用 PDO::prepare() 来准备一个 PDOStatement 对象并用 PDOStatement::execute() 发出语句。
PDO::exec支持SELECT/DELETE/UPDATE/INSERT等全部SQL语句执行,所以相比PDO query()函数功能要强大的多。由于只返回受影响的函数,所以,如果执行SELECT则无法得到PDOStatement对象,故也无法遍历结果集,只能按照官方建议去使用query或execute函数。。
3.prepare的原理是这样的,预先把sql语句发送给sql server进行编译,等exec的时候再真正的执行。一次编译,多次执行。如果只是一次查询的话,prepare和query效率基本相当。如果多次执行,prepare的效率就会提现出来。另外并不是所有sql注入都可以防止,where in(“ ”)这样的就不行。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏