Ответ 1
В целом "take" будет быстрее, потому что базе данных не нужно идентифицировать все строки, соответствующие критериям, а затем сортировать их и находить строку с наименьшей сортировкой. "take" позволяет базе данных остановиться, как только она найдет одну строку.
Степень, в которой она быстрее, будет меняться в зависимости от:
-
Сколько времени сохраняется, если вам не нужно искать несколько строк. В худшем случае здесь требуется полное сканирование большой таблицы, но одна соответствующая строка найдена очень рано в сканировании. "take" позволит остановить сканирование.
-
Сколько строк нужно отсортировать, чтобы найти тот, у которого самый низкий идентификатор. В худшем случае здесь каждая строка в таблице соответствует критериям и должна быть включена в сортировку.
Есть несколько других факторов, которые следует учитывать - например, для "первого" запроса оптимизатор может иметь доступ к таблице с помощью проверки индекса первичного ключа и проверять каждую строку, чтобы убедиться, что она соответствует условию. Если есть очень высокая вероятность этого, то и полное сканирование данных и сортировка можно избежать, если оптимизатор запросов достаточно сложный.
Во многих случаях, когда для их поиска очень мало совпадающих записей и доступа на основе индексов, вы обнаружите, что разница тривиальна (там, где в вашем примере есть уникальный индекс в "электронной почте" ). Тем не менее, я бы по-прежнему использовал "взять", предпочитая сначала даже тогда.
Изменить: я просто добавлю, хотя это немного не по теме, что в вашем примере вы также можете использовать:
User.find_by(email: '[email protected]')
Сгенерированный запрос должен быть таким же, как и для take, но семантика немного ясна.