他们是在做同样的事情,只是不同而已?
除了使用prepare
之外,还有什么区别吗?
$sth = $db->query("SELECT * FROM table");
$result = $sth->fetchAll();
和
$sth = $db->prepare("SELECT * FROM table");
$sth->execute();
$result = $sth->fetchAll();
发布于 2011-01-16 00:38:22
query
运行标准的SQL语句,并要求您正确地转义所有数据,以避免SQL注入和其他问题。
execute
运行预准备语句,该语句允许您绑定参数以避免对参数进行转义或引用。如果您重复多次查询,execute
的性能也会更好。预准备语句示例:
$sth = $dbh->prepare('SELECT name, colour, calories FROM fruit
WHERE calories < :calories AND colour = :colour');
$sth->bindParam(':calories', $calories);
$sth->bindParam(':colour', $colour);
$sth->execute();
// $calories or $color do not need to be escaped or quoted since the
// data is separated from the query
最佳实践是坚持使用预准备语句和 execute
,以提高安全性。
另请参阅:Are PDO prepared statements sufficient to prevent SQL injection?
发布于 2011-01-16 00:41:55
不,它们是不一样的。除了它在客户端提供的转义之外,预准备语句在服务器端编译一次,然后可以在每次执行时传递不同的参数。这意味着您可以执行以下操作:
$sth = $db->prepare("SELECT * FROM table WHERE foo = ?");
$sth->execute(array(1));
$results = $sth->fetchAll(PDO::FETCH_ASSOC);
$sth->execute(array(2));
$results = $sth->fetchAll(PDO::FETCH_ASSOC);
它们通常会给您带来性能改进,尽管在小范围内不是很明显。Read more on prepared statements (MySQL version)。
发布于 2016-10-07 23:59:02
Gilean's answer很棒,但我只想补充一点,有时最佳实践很少有例外,您可能希望以两种方式测试您的环境,看看哪种方式工作得最好。
有一次,我发现query
对我来说工作得更快,因为我从运行PHP7的Ubuntu Linux机器批量传输可信数据,而Microsoft ODBC driver for MS SQL Server的支持很差。
我提出这个问题是因为我有一个长时间运行的ETL脚本,我试图压缩它以提高速度。在我看来,query
可能比prepare
& execute
更快,因为它只调用一个函数,而不是两个。参数绑定操作提供了很好的保护,但它可能很昂贵,如果不必要,还可以避免。
给出了几个罕见的条件
如果你因为it's not supported by the Microsoft ODBC driver.
PDO::lastInsertId
。这是我用来测试我的环境的一种方法,希望你能在你的环境中复制它或更好的东西:
首先,我在Microsoft SQL Server中创建了一个基本表
CREATE TABLE performancetest (
sid INT IDENTITY PRIMARY KEY,
id INT,
val VARCHAR(100)
);
现在是性能指标的基本计时测试。
$logs = [];
$test = function (String $type, Int $count = 3000) use ($pdo, &$logs) {
$start = microtime(true);
$i = 0;
while ($i < $count) {
$sql = "INSERT INTO performancetest (id, val) OUTPUT INSERTED.sid VALUES ($i,'value $i')";
if ($type === 'query') {
$smt = $pdo->query($sql);
} else {
$smt = $pdo->prepare($sql);
$smt ->execute();
}
$sid = $smt->fetch(PDO::FETCH_ASSOC)['sid'];
$i++;
}
$total = (microtime(true) - $start);
$logs[$type] []= $total;
echo "$total $type\n";
};
$trials = 15;
$i = 0;
while ($i < $trials) {
if (random_int(0,1) === 0) {
$test('query');
} else {
$test('prepare');
}
$i++;
}
foreach ($logs as $type => $log) {
$total = 0;
foreach ($log as $record) {
$total += $record;
}
$count = count($log);
echo "($count) $type Average: ".$total/$count.PHP_EOL;
}
我已经在我的特定环境中尝试了多个不同的试验和计数,并且始终比prepare
/execute
使用query
快20-30%的结果
5.8128969669342准备
5.8688418865204准备
4.2948560714722查询
4.9533629417419查询
5.9051351547241准备
4.332102060318查询
5.9672858715057准备
5.0667371749878查询
3.8260300159454查询
4.0791549682617查询
4.3775160312653查询
3.6910600662231查询
5.2708210945129准备
6.2671611309052准备
7.3791449069977准备
(7)准备平均值: 6.0673267160143
(8)平均查询次数: 4.3276024162769
我很想看看这个测试在其他环境中的比较情况,比如MySQL。
https://stackoverflow.com/questions/4700623
复制相似问题