Производительность: использование try (оператор) и catch (выходная ошибка) вместо проверки, если электронная почта уже существует - PullRequest
1 голос
/ 02 апреля 2019

Очень часто мне нужно, чтобы запросы не выполнялись, когда значение, подобное электронной почте, уже существует.

До сих пор я искал такое значение:

$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 Ответ

4 голосов
/ 02 апреля 2019

После того как столбец uid стал [уникальным] индексом, вы сделали все ваши запросы быстрее. Оба запроса, либо SELECT, либо INSERT, должны будут проверить индекс, и будет выполнять их оба одновременно .

Добавление индекса к столбцу, используемому для поиска, является реальным ответом на ваш вопрос . Вопрос о том, использовать ли запрос выбора или перехватить исключение во время вставки, является делом вкуса.

Однако ваш второй пример довольно неверен. Вы не должны обрабатывать все исключения PDO одинаково, а только конкретное исключение, связанное с этим же случаем, как показано в моем руководстве по PDO .

Лучший способ - сохранить уникальный индекс, но добавить в запрос ключевое слово IGNORE, а затем проверить количество затронутых строк

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

добавление IGNORE подавит ошибку уникального индекса, и вы сможете проверить, существует ли такое значение, просто проверив количество затронутых строк

...