Почему плохо использовать звездочку (*) в SQL запросах
Что проверяют
Понимаете ли вы, что запрос это контракт между приложением и базой, а не быстрый способ посмотреть данные. В питоновском коде звёздочка почти всегда доезжает до драйвера и дальше в сериализацию, поэтому проверяют, представляете ли вы, что происходит с результатом после базы.
Как отвечать
Разложите последствия по слоям.
База читает и отдаёт лишние колонки, вытаскивает из отдельного хранилища тяжёлые текстовые и json поля, а главное, запрос перестаёт закрываться индексом: выборка двух колонок, которые в индекс уже входят, читается прямо из него, а select * заставляет идти в таблицу за каждой строкой.
Приложение получает результат, который меняется молча. Добавили колонку миграцией, и новое поле уехало в ответ API или в лог. Код, который берёт значения по номеру (row[3]), ломается от перестановки колонок, а в соединении таблиц с одинаковыми именами колонок вы получаете два поля с одним именем.
Оговорите исключения, иначе ответ звучит заученным: count(*) и exists (select 1 ...) к этому правилу отношения не имеют, разовый разбор в консоли тоже. Явный список колонок нужен коду, который живёт в репозитории и переживёт следующую миграцию.
Где спотыкаются
Начинают с безопасности. Утечка происходит не в базе, а в сериализаторе, который отдаёт наружу всё, что пришло. Если модель ответа собирается явно, лишняя колонка до клиента не доедет, и аргумент рассыпается.
Говорят «медленнее», не объясняя чем. Разница не в разборе запроса, а в объёме чтения и в потере возможности ответить одним индексом, и на узкой таблице из трёх колонок её может не быть вовсе.
Считают, что ORM снимает вопрос. Запрос по модели тоже тянет все колонки, включая длинный текст, и чтобы взять нужные, поля перечисляют явно, а связанные объекты подгружают одним запросом вместо доставания по одному.