Что будет если сделать select 1 вместо названия колонки
Что проверяют
Понимаете ли вы, что список выборки в подзапросе EXISTS планировщик игнорирует, и не путаете ли удобную идиому с оптимизацией. Вопрос быстрый, но по нему видно, читаете ли вы планы запросов или повторяете советы из статей.
Как отвечать
SELECT 1 FROM t WHERE ... возвращает по одной строке со значением 1 на каждую подходящую строку таблицы. Данные колонок при этом не читаются, но строки всё равно ищутся и фильтруются, поэтому стоимость определяется способом доступа, а не списком выборки.
Главная область применения это проверка существования:
select exists (
select 1 from orders where user_id = 42
);Внутри EXISTS пишут 1 ради читаемости, чтобы никто не искал смысла в списке колонок. На производительность это не влияет: SELECT 1, SELECT * и SELECT id дадут одинаковый план, потому что подзапрос останавливается на первой найденной строке. То же самое с count(1) и count(*), разницы нет.
Вторая типовая роль это проба соединения: пул перед выдачей соединения выполняет select 1 и убеждается, что оно живое.
Если нужна сама строка, SELECT 1 бесполезен, он не скажет, какая именно строка нашлась. Тогда берут конкретную колонку и добавляют limit 1.
Где спотыкаются
Утверждают, что SELECT 1 быстрее, чем SELECT *. В контексте EXISTS это миф. Разница появляется только в обычном запросе, где чтение широких колонок действительно стоит денег, а короткий список выборки иногда позволяет обойтись сканированием одного индекса.
Второе: заменяют EXISTS на IN с подзапросом и попадают на NULL. Если подзапрос вернёт хотя бы один NULL, NOT IN перестанет возвращать строки вовсе, а NOT EXISTS поведёт себя как ожидается.
Третье: используют count(*) > 0 там, где нужен EXISTS. Подсчёт обходит все подходящие строки, проверка существования останавливается на первой, и на большой таблице это разница в порядки.