← Назад к вопросам

В чем разница между SELECT * FROM и SELECT (перечисление всех полей) FROM?

1.7 Middle🔥 141 комментариев
#Базы данных и SQL

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Разница между SELECT * и SELECT (перечисление полей)

Основное определение

**SELECT *** — выбирает ВСЕ поля из таблицы автоматически. SELECT col1, col2, col3 — выбирает только указанные поля.

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

SELECT * — все поля

Выбирает все столбцы:

SELECT * FROM users;

Проблемы:

  • Избыточные данные (читаются ненужные поля)
  • Скрытая зависимость (новые поля добавляются автоматически)
  • Медленнее (больше трафика)
  • Проблемы с безопасностью (могут вернуться чувствительные данные)

SELECT col1, col2 — явное перечисление

Выбирает только нужные:

SELECT id, name, email FROM users;

Преимущества:

  • Только нужные данные
  • Ясно, что используется
  • Быстрее
  • Безопаснее
  • Защита от изменений схемы

Практический пример

Таблица с 30 полями, нужны 3:

-- Плохо: читает 30 полей
SELECT * FROM orders WHERE status = "completed";

-- Хорошо: читает 4 поля (экономия 86% трафика)
SELECT id, user_id, product_id, price FROM orders WHERE status = "completed";

С JOIN

-- Плохо: 45 полей из трёх таблиц
SELECT * FROM users u
JOIN orders o ON u.id = o.user_id
JOIN products p ON o.product_id = p.id;

-- Хорошо: только нужные 7 полей
SELECT u.id, u.name, o.id, o.created_at, p.name, p.price
FROM users u
JOIN orders o ON u.id = o.user_id
JOIN products p ON o.product_id = p.id;

Проблема с добавлением полей

-- Исходно
SELECT * FROM users;  -- 5 полей

-- Потом добавили новые колонки
ALTER TABLE users ADD COLUMN password_hash VARCHAR(255);
ALTER TABLE users ADD COLUMN phone VARCHAR(20);

-- Теперь SELECT * возвращает 8 полей (включая пароли!)
-- А вот явный SELECT остался прежним
SELECT id, name, email FROM users;  -- всё так же 3 поля

Безопасность

-- Опасно: может вернуть пароли и личные данные
SELECT * FROM users;

-- Безопасно: только публичные поля
SELECT id, name, email FROM users;

Java пример

// Плохо
public List<UserDTO> getUsers() throws SQLException {
    ResultSet rs = stmt.executeQuery("SELECT * FROM users");
    // обработка
}

// Хорошо
public List<UserDTO> getUsers() throws SQLException {
    String sql = "SELECT id, name, email FROM users";
    ResultSet rs = stmt.executeQuery(sql);
    // обработка
}

// Лучше всего — с ORM
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    @Query("SELECT new com.example.UserDTO(u.id, u.name, u.email) FROM User u")
    List<UserDTO> findAllProjected();
}

Когда использовать

SELECT * приемлем:

  • Exploratory queries в dev
  • Таблицы с 2-3 полями
  • Админ-инструменты

SELECT col1, col2 обязателен:

  • Production код
  • API endpoints
  • JOIN запросы
  • Большие таблицы
  • Чувствительные данные

Сравнение

АспектSELECT *SELECT col1, col2
ПроизводительностьМедленнееБыстрее
БезопасностьРискКонтролируется
ПоддерживаемостьХрупкийЯвный
Изменения схемыСкрытые проблемыЗащищено
ИспользованиеExploration, devProduction

Итог

В production коде ВСЕГДА используй явное перечисление полей. SELECT * приемлем только для ad-hoc запросов в разработке.