首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >PDO的查询与执行

PDO的查询与执行
EN

Stack Overflow用户
提问于 2011-01-16 00:12:22
回答 3查看 143.2K关注 0票数 133

他们是在做同样的事情,只是不同而已?

除了使用prepare之外,还有什么区别吗?

代码语言:javascript
复制
$sth = $db->query("SELECT * FROM table");
$result = $sth->fetchAll();

代码语言:javascript
复制
$sth = $db->prepare("SELECT * FROM table");
$sth->execute();
$result = $sth->fetchAll();
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-01-16 00:38:22

query运行标准的SQL语句,并要求您正确地转义所有数据,以避免SQL注入和其他问题。

execute运行预准备语句,该语句允许您绑定参数以避免对参数进行转义或引用。如果您重复多次查询,execute的性能也会更好。预准备语句示例:

代码语言:javascript
复制
$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?

票数 149
EN

Stack Overflow用户

发布于 2011-01-16 00:41:55

不,它们是不一样的。除了它在客户端提供的转义之外,预准备语句在服务器端编译一次,然后可以在每次执行时传递不同的参数。这意味着您可以执行以下操作:

代码语言:javascript
复制
$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)

票数 49
EN

Stack Overflow用户

发布于 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.

  • If而不能重用一个准备好的语句,你不需要担心清理输入,简单的转义是可以接受的。
  1. 。这可能是因为Microsoft驱动程序不支持binding certain datatypes isn't supported by the Microsoft ODBC driver.
  2. PDO::lastInsertId

这是我用来测试我的环境的一种方法,希望你能在你的环境中复制它或更好的东西:

首先,我在Microsoft SQL Server中创建了一个基本表

代码语言:javascript
复制
CREATE TABLE performancetest (
    sid INT IDENTITY PRIMARY KEY,
    id INT,
    val VARCHAR(100)
);

现在是性能指标的基本计时测试。

代码语言:javascript
复制
$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。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4700623

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档