Суть цитаты о преждевременной оптимизации заключается в том, чтобы перейти к простому и понятному коду, а затем использовать профилировщик, чтобы указать на горячие точки, которые затем можно оптимизировать для повышения эффективности.
Когда вы используете select *, вы делаете невозможным профилирование, поэтому вы не пишете четкий и понятный код и идете вразрез с духом цитаты. select *
это анти-шаблон.
Таким образом, выбор столбцов не является преждевременной оптимизацией. Несколько вещей с моей головы ....
- Если вы укажете столбцы в операторе SQL, механизм выполнения SQL выдаст ошибку, если этот столбец будет удален из таблицы и запрос будет выполнен.
- Вы можете легче сканировать код, где используется этот столбец.
- Вы всегда должны писать запросы, чтобы вернуть наименьшее количество информации.
- Как говорят другие, если вы используете порядковый доступ к столбцу, вы никогда не должны использовать select *
- Если ваш оператор SQL объединяет таблицы, выберите *, чтобы получить все столбцы из всех таблиц в объединении
Следствием является то, что с помощью select *
...
- Столбцы, используемые приложением, непрозрачны
- Администраторы баз данных и их профилировщики запросов не могут помочь в низкой производительности вашего приложения
- Код становится более хрупким, когда происходят изменения
- Ваша база данных и сеть страдают, потому что они возвращают слишком много данных (I / O)
- Оптимизация ядра СУБД минимальна, поскольку вы возвращаете все данные независимо (логично).
Написание правильного SQL так же просто, как и написание Select *
. Таким образом, настоящий ленивый человек пишет правильный SQL, потому что он не хочет пересматривать код и пытаться вспомнить, что он делал, когда делал это. Они не хотят объяснять администратору базы данных каждый бит кода. Они не хотят объяснять своим клиентам, почему приложение работает как собака.
Если ваш код зависит от расположения столбцов в определенном порядке, ваш код будет поврежден при изменении таблицы. Кроме того, когда вы выбираете *, вы можете извлечь слишком много из таблицы, особенно если в таблице есть двоичное поле.
То, что вы сейчас используете все столбцы, не означает, что кто-то другой не собирается добавлять дополнительный столбец в таблицу.
Это также увеличивает накладные расходы на кэширование выполнения плана, так как ему необходимо извлечь метаданные о таблице, чтобы узнать, какие столбцы находятся в *.
источник
Одна из основных причин заключается в том, что если вы когда-либо добавляете / удаляете столбцы из таблицы, любой запрос / процедура, выполняющая вызов SELECT *, теперь будет получать больше или меньше столбцов данных, чем ожидалось.
источник
Обходным путем вы нарушаете правило модульности о строгой типизации, где это возможно. Явное почти всегда лучше.
Даже если вам теперь нужен каждый столбец в таблице, позже можно будет добавить больше, которые будут сноситься каждый раз, когда вы выполняете запрос, что может снизить производительность. Это ухудшает производительность, потому что
Когда использовать выберите *
Когда вам явно НУЖЕН каждый столбец в таблице, в отличие от необходимости каждого столбца в таблице, ЧТО СУЩЕСТВУЕТ ВО ВРЕМЯ, ВЫ ЗАПИСАЛИ ЗАПРОС. Например, если вы пишете приложение для управления БД, которое должно отображать все содержимое таблицы (каким бы оно ни было), вы можете использовать этот подход.
источник
SELECT *
тестовые запросы с использованием клиента db.Есть несколько причин:
Примечание: я выбрал INTEGER в приведенном выше примере, потому что они имеют фиксированный размер 4 байта.
источник
Если ваше приложение получает данные с помощью SELECT *, и структура таблицы в базе данных изменяется (скажем, столбец удаляется), ваше приложение будет отказывать в каждом месте, где вы ссылаетесь на отсутствующее поле. Если вместо этого вы включите все столбцы в свой запрос, ваше приложение сломается (надеюсь) в одном месте, где вы изначально получаете данные, что упростит исправление.
При этом существует ряд ситуаций, в которых SELECT * желателен. Одна из них - это ситуация, с которой я сталкиваюсь все время, когда мне нужно скопировать всю таблицу в другую базу данных (например, с SQL Server на DB2). Другим является приложение, написанное для общего отображения таблиц (т.е. без каких-либо знаний о какой-либо конкретной таблице).
источник
Я действительно заметил странное поведение, когда я использовал
select *
в представлениях в SQL Server 2005.Запустите следующий запрос, и вы поймете, что я имею в виду.
Сравните результаты двух последних утверждений. Я полагаю, что то, что вы увидите, является результатом выбора столбцов со ссылкой Select * по индексу, а не по имени.
Если вы восстановите вид, он снова будет работать нормально.
РЕДАКТИРОВАТЬ
Я добавил отдельный вопрос: * «выберите * из таблицы» против «выберите colA, colB и т. Д. Из таблицы» - интересное поведение в SQL Server 2005 *, чтобы подробнее рассмотреть это поведение.
источник
Вы можете объединить две таблицы и использовать столбец A из второй таблицы. Если позже вы добавите столбец A к первой таблице (с тем же именем, но, возможно, с другим значением), вы, скорее всего, получите значения из первой таблицы, а не второй, как ранее. Этого не произойдет, если вы явно укажете столбцы, которые хотите выбрать.
Конечно, указание столбцов также иногда вызывает ошибки, если вы забыли добавить новые столбцы в каждое предложение select. Если новый столбец не нужен каждый раз, когда выполняется запрос, может пройти некоторое время, прежде чем ошибка будет замечена.
источник
Я понимаю, куда вы идете в отношении преждевременной оптимизации, но на самом деле это только доходит до точки. Цель состоит в том, чтобы избежать ненужного оптимизации в начале. Ваши таблицы не проиндексированы? Вы бы использовали nvarchar (4000) для хранения почтового индекса?
Как уже отмечали другие, есть и другие плюсы при указании каждого столбца, который вы собираетесь использовать в запросе (например, ремонтопригодность).
источник
Когда вы указываете столбцы, вы также привязываете себя к определенному набору столбцов и делаете себя менее гибким, заставляя Feuerstein переворачиваться, ну, где бы он ни был. Просто мысль.
источник
SELECT * не всегда зло. По моему, по крайней мере. Я использую его довольно часто для динамических запросов, возвращающих всю таблицу, а также некоторые вычисляемые поля.
Например, я хочу вычислить географические геометрии из «нормальной» таблицы, то есть таблицы без какого-либо геометрического поля, но с полями, содержащими координаты. Я использую postgresql, и его пространственное расширение postgis. Но принцип применяется для многих других случаев.
Пример:
таблица мест с координатами, хранящимися в полях, помеченных x, y, z:
CREATE TABLE Places (place_id integer, x числовой (10, 3), y числовой (10, 3), z числовой (10, 3), описание varchar);
давайте накормим его несколькими примерами значений:
INSERT INTO place (place_id, x, y, z, description) VALUES
(1, 2.295, 48.863, 64, «Paris, Place de l \ 'Étoile»),
(2, 2.945, 48.858, 40, «Paris, Tour Eiffel» «),
(3, 0,373, 43,958, 90, "Condom, Cathédrale St-Pierre");
Я хочу иметь возможность отобразить содержимое этой таблицы, используя некоторый ГИС-клиент. Обычным способом является добавление поля геометрии в таблицу и построение геометрии на основе координат. Но я бы предпочел получить динамический запрос: таким образом, когда я меняю координаты (исправления, большую точность и т. Д.), Отображаемые объекты фактически перемещаются динамически. Итак, вот запрос с помощью SELECT * :
СОЗДАТЬ ИЛИ ЗАМЕНИТЬ VIEW place_points AS
SELECT *,
GeomFromewkt ('SRID = 4326; POINT (' || x || '' || y || '' || z || ')')
ОТ мест;
Обратитесь к postgis, для использования функции GeomFromewkt ().
Вот результат:
SELECT * FROM place_points;
Крайний правый столбец теперь может использоваться любой ГИС-программой для правильного отображения точек.
Хотелось бы, чтобы определение VIEW могло быть сохранено "как есть" с помощью *, но пока дело не в этом: это то, как он внутренне хранится в postgresql:
Выберите пункты : текст) || местах.у) || '' :: текст) || места.з) || ')' :: текст) AS geomfromewkt ОТ мест;
источник
Даже если вы используете каждый столбец, но адрес строки массива по числовому индексу, у вас будут проблемы, если позже вы добавите еще одну строку.
Так что в основном это вопрос ремонтопригодности! Если вы не используете селектор *, вам не придется беспокоиться о своих запросах.
источник
Выбор только нужных столбцов уменьшает размер набора данных в памяти и, следовательно, ускоряет работу приложения.
Кроме того, многие инструменты (например, хранимые процедуры) также кэшируют планы выполнения запросов. Если позже вы добавите или удалите столбец (особенно легко, если вы выбираете представление), инструмент часто будет выдавать ошибку, если не вернет ожидаемые результаты.
источник
Это делает ваш код более двусмысленным и более сложным в обслуживании; потому что вы добавляете дополнительные неиспользуемые данные в домен, и неясно, что вы намеревались, а какие нет. (Это также предполагает, что вы можете не знать или не заботиться.)
источник
Чтобы ответить на ваш вопрос напрямую: не используйте «SELECT *», когда он делает ваш код более уязвимым к изменениям в базовых таблицах. Ваш код должен ломаться только тогда, когда в таблицу вносятся изменения, которые напрямую влияют на требования вашей программы.
Ваше приложение должно использовать уровень абстракции, предоставляемый реляционным доступом.
источник
Я не использую SELECT * просто потому, что приятно видеть и знать, какие поля я получаю.
источник
Как правило, плохо использовать 'select *' внутри представлений, потому что вам придется перекомпилировать представление в случае изменения столбца таблицы. Изменяя базовые столбцы таблицы представления, вы получите ошибку для несуществующих столбцов, пока не вернетесь и не перекомпилируете.
источник
Это нормально, когда вы делаете,
exists(select * ...)
так как он никогда не расширяется. В противном случае это действительно полезно только при исследовании таблиц с временными выбранными утверждениями или если у вас был определен CTE выше, и вы хотите, чтобы каждый столбец не печатался снова.источник
Просто чтобы добавить одну вещь, которую никто не упомянул.
Select *
возвращает все столбцы, кто-то может позже добавить столбец, который вы не обязательно хотите, чтобы пользователи могли видеть, например, кто в последний раз обновил данные или отметку времени или заметки, которые должны видеть только все пользователи, не все пользователи и т. д.Кроме того, при добавлении столбца следует проанализировать влияние на существующий код и рассмотреть вопрос о необходимости внесения изменений в зависимости от того, какая информация хранится в столбце. При использовании
select *
этого обзора часто пропускают, потому что разработчик предположит, что ничего не сломается. И на самом деле ничто явно не может сломаться, но теперь запросы могут начать возвращать не ту вещь. То, что ничего явно не нарушается, не означает, что в запросах не должно быть изменений.источник
потому что «select *» будет тратить память, когда вам не нужны все поля. Но для сервера sql их производительность одинакова.
источник