他们都做同样的事情,只是区别对待吗?
除了使用prepare之间有什么区别
$sth = $db->query("SELECT * FROM table");
$result = $sth->fetchAll();
Run Code Online (Sandbox Code Playgroud)
和
$sth = $db->prepare("SELECT * FROM table");
$sth->execute();
$result = $sth->fetchAll();
Run Code Online (Sandbox Code Playgroud)
?
Gil*_*ean 142
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
Run Code Online (Sandbox Code Playgroud)
最佳做法是坚持准备好的陈述并execute提高安全性.
net*_*der 46
不,他们不一样.除了它提供的客户端上的转义之外,在服务器端编译一个预准备语句,然后在每次执行时传递不同的参数.这意味着你可以做到:
$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);
Run Code Online (Sandbox Code Playgroud)
它们通常会为您提供性能改进,尽管在小规模上并不明显.阅读有关预准备语句的更多信息(MySQL版本).
Gilean 的回答很好,但我只是想补充一点,有时最佳实践很少有例外,您可能希望以两种方式测试您的环境,看看哪种方法最有效。
在一种情况下,我发现它对query我的目的来说工作得更快,因为我从运行 PHP7 的 Ubuntu Linux 机器上批量传输可信数据,而MS SQL Server 的 Microsoft ODBC 驱动程序支持不佳。
我提出这个问题是因为我有一个长时间运行的ETL脚本,我试图提高速度。对我来说,直觉似乎query可能比prepare&更快execute,因为它只调用一个函数而不是两个。参数绑定操作提供了极好的保护,但可能会很昂贵,如果不必要的话可以避免。
考虑到几个罕见的条件:
如果由于Microsoft ODBC 驱动程序不支持而无法重用准备好的语句。
如果您不担心清理输入,那么简单的转义是可以接受的。出现这种情况的原因可能是Microsoft ODBC 驱动程序不支持绑定某些数据类型。
PDO::lastInsertIdMicrosoft ODBC 驱动程序不支持。
这是我用来测试我的环境的方法,希望您可以在您的环境中复制它或更好的方法:
首先,我在 Microsoft SQL Server 中创建了一个基本表
CREATE TABLE performancetest (
sid INT IDENTITY PRIMARY KEY,
id INT,
val VARCHAR(100)
);
Run Code Online (Sandbox Code Playgroud)
现在是性能指标的基本定时测试。
$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;
}
Run Code Online (Sandbox Code Playgroud)
我在特定环境中进行了多次不同的试验和计数,并且始终获得query比prepare/快 20-30% 的结果execute
5.8128969669342 prepare
5.8688418865204 prepare
4.2948560714722 query
4.9533629417419 query
5.9051351547241 prepare
4.332102060318 query
5.9672858715057 prepare
5.0667371749878 query
3.8260300159454 query
4.0791549682617 query
4.3775160312653 query
3.6910600662231 query
5.2708210945129 prepare
6.2671611309052 prepare
7.3791449069977 prepare
(7) prepare Average: 6.0673267160143
(8) query Average: 4.3276024162769
我很好奇这个测试在其他环境(例如 MySQL)中的比较如何。
| 归档时间: |
|
| 查看次数: |
131664 次 |
| 最近记录: |