性能:使用try(语句)和catch(输出错误),而不是检查电子邮件是否已存在

时间:2019-04-02 14:47:39

标签: php performance pdo database-performance query-performance

通常,当电子邮件之类的值已经存在时,我经常需要阻止查询执行。

直到现在我一直搜索这样的值:

$checkemailexist = $X['db']->prepare("SELECT uid FROM userdata WHERE uid = :uid LIMIT 1");
$checkemailexist->execute(array(
':uid'=>$uid
));

if(empty($checkemailexist)){
   INSERT QUERY ..
}

...

在具有许多行的大型数据库上的问题,甚至在varchar上进行字符串搜索都需要大量的性能和时间。

所以我使uid列唯一,并尝试了类似的操作:

try{    
    $insertuser = $X['dbh']->prepare("
    INSERT INTO user (uid) VALUES (:uid) 
    ");

    $insertuser->execute(array(
    ':uid'=> $mail
    ));

} catch (PDOException $e) {
        header("Location: ...");
        exit(); 
}


它工作正常,但是性能会更差吗?

1 个答案:

答案 0 :(得分:4)

将uid列设为[唯一]索引后,您可以使 all 查询更快。这两个查询(无论是SELECT还是INSERT)都必须检查索引,并且同时执行这两个查询

在用于搜索的列中添加索引是您问题的真正答案。至于在插入过程中使用选择查询还是捕获异常是一个问题。

但是,您的第二个示例是相当错误的。您不应该以相同的方式处理每个PDOException,而是仅处理与这种情况相关的特定异常,如我的PDO tutorial所示。

最好的方法是保留唯一索引,但在查询中添加关键字IGNORE,然后检查受影响的行数

$insertuser = $X['dbh']->prepare("INSERT IGNORE INTO user (uid) VALUES (:uid)");
$insertuser->execute(['uid'=> $mail]));
if (!$insertuser->numRows()) {
    header("Location: ...");
    exit(); 
} 

添加IGNORE可以消除唯一索引错误,您只需检查受影响的行数就可以检查该值是否已经存在