← Назад к вопросам
В чем разница между 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, dev | Production |
Итог
В production коде ВСЕГДА используй явное перечисление полей. SELECT * приемлем только для ad-hoc запросов в разработке.