通常,当电子邮件之类的值已经存在时,我经常需要阻止查询执行。
直到现在我一直搜索这样的值:
$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();
}
它工作正常,但是性能会更差吗?
答案 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可以消除唯一索引错误,您只需检查受影响的行数就可以检查该值是否已经存在