Есть ли разница между Select * и Select [перечислить каждый столбец]

Я использую MS SQL Server 2005. Есть ли разница для механизма SQL между

SELECT * FROM MyTable;

и

SELECT ColA, ColB, ColC FROM MyTable;

Когда ColA, ColB и ColC представляют каждый столбец в таблице?

Если они такие же, есть ли причина, по которой вы все равно должны использовать второй? У меня есть проект, в котором много LINQ, и я не уверен, что генерируемый им стандартный SELECT * - плохая практика, или я всегда должен использовать для него .Select (), чтобы указать, какие столбцы мне нужны.

Обновлено: Изменено «Когда ColA, ColB и ColC - все столбцы в таблице?» на «Когда ColA, ColB и ColC представляют каждый столбец в таблице?» для ясности.

См. Также: stackoverflow.com/questions/65512/…

Annika Backstrom 12.08.2009 16:46
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
25
1
7 835
18
Перейти к ответу Данный вопрос помечен как решенный

Ответы 18

Когда вы выбираете каждое поле по отдельности, становится более ясно, какие именно поля выбираются.

Ответ принят как подходящий

Как правило, лучше быть явным, поэтому Select col1, col2 from Table лучше. Причина в том, что в какой-то момент в эту таблицу может быть добавлен дополнительный столбец, что приведет к возврату ненужных данных из запроса.

Однако это не жесткое правило.

Во многих случаях это также вызывает сбой зависимого кода. Это особенно верно в средах с ленивыми разработчиками, которые не используют списки столбцов в операторах INSERT.

Pittsburgh DBA 16.10.2008 19:18

однако в некоторых случаях явное выражение означает, что вам, возможно, придется изменить каждый отдельный код, который использует таблицу, поскольку вы делать хотите, чтобы новый столбец отображался почти везде. Хотя вам часто все еще необходимо изменить код представления, простой переход с * все равно сократит работу вдвое в этих случаях. Все зависит от того, что вы делаете, и каковы ваши планы на будущее.

Lie Ryan 21.03.2011 20:00

с точки зрения разработчиков, это не так хорошо, потому что если вам придется изменить или удалить имя столбца, это вызовет панику, потому что вам придется менять его везде. но, сэр @swilliams, есть ли у него какие-то преимущества в производительности?

santosh 31.10.2018 11:10

1) Второй вариант более четко определяет, какие столбцы возвращаются. Тогда значение второго - это то, насколько вы цените, зная, какие столбцы возвращаются.

2) Это подразумевает, что возвращается потенциально меньше данных, когда столбцов больше, чем явно используемых.

3) Если вы измените таблицу, добавив новый столбец, первый запрос изменится, а второй - нет. Если у вас есть код типа «для всех возвращаемых столбцов сделать ...», то результаты изменятся, если вы используете первый, но не второй.

Некоторые причины не использовать первого оператора (выберите *):

  1. Если вы добавите несколько больших полей (столбец BLOB будет очень плохим) позже в эту таблицу, вы можете столкнуться с проблемы с производительностью в приложении
  2. Если запрос был запросом JOIN с двумя или более таблицами, некоторые поля могли иметь то же имя. Лучше заверить, что имена ваших полей разные.
  3. цель запроса более понятен со вторым утверждением с точки зрения эстетики программирования.

Я не против твоего ответа. но большинство баз данных используют отдельные вызовы для загрузки типов Large Object(BLOB), когда для набора результатов запрашивается соответствующий метод получения. Таким образом, производительность снижается только тогда, когда вы действительно хотите, чтобы эти столбцы были прочитаны.

Raja Anbazhagan 28.03.2018 16:09

Вы должны указать явный список столбцов. SELECT * вернет больше столбцов, чем вам нужно, для создания большего количества операций ввода-вывода и сетевого трафика, но, что более важно, может потребоваться дополнительный поиск, даже если существует некластеризованный покрывающий индекс (на SQL Server).

Да! Это лучшая причина для ясности - индексы покрытия.

Michael Haren 16.10.2008 19:11

Принятый ответ, кажется, удовлетворяет [неправильные] представления большинства людей о разнице между * и col1, col2, col3.

ProfK 03.01.2010 02:05

Беглый взгляд на план выполнения запроса показывает, что запросы совпадают.

Общее практическое правило состоит в том, что вы захотите ограничить свои запросы только теми полями, которые вам нужно вернуть.

Это хорошо для прямой совместимости.

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

SELECT * FROM myTable

а в «myTable» 3 столбца. Вы получите те же результаты, что и

SELECT Column1, Column2, Column3 FROM myTable

Но если вы добавите новый столбец в будущем, вы получите другие результаты.

Конечно, если вы измените имя одного из существующих столбцов, в первом случае вы получите результат, а во втором случае вы получите ошибку (я думаю, это правильное поведение приложения).

Я не уверен, что нарушение при будущих изменениях - это определение прямой совместимости.

Mark Brady 16.10.2008 19:11

Я думаю, что аргументы TcKs заключаются в том, что взломать лучше, чем делать вид, что работает (но не работает).

Greg D 16.10.2008 19:15

Я согласен, приложение должно сломаться, если вы переименуете столбец и получите доступ к результатам по имени столбца. Использование * ничуть не лучше для защиты от переименования, если вы по-прежнему получаете доступ к результатам по имени столбца, а не по индексу.

Josh 16.10.2008 19:17

@Greg D Да, именно это я и имел в виду.

TcKs 17.10.2008 12:33

Для LinqToSql, если вы планируете изменить эти записи позже, вы должны вытащить всю запись в память.

SELECT * - это плохая практика в большинстве случаев.

  • Что, если кто-то добавит в эту таблицу столбец BLOB размером 2 ГБ?
  • Что кто-то действительно добавляет в эту таблицу какой-нибудь столбец?

Это ошибка, которая ждет своего часа.

"SELECT *" не вернет 2 гига, так что это не имеет значения. Это добавление столбцов, влияющих на зависимый код, наряду с удобочитаемостью и ясностью, что действительно имеет значение.

Pittsburgh DBA 16.10.2008 19:15

Я в основном согласен, за исключением части ошибки. Я обнаружил, что смог избежать ошибок, просто получив всю строку и имея только одно место (класс уровня доступа к данным) для обработки этих данных. Я обычно решаю возможные проблемы там. классы модели данных со ссылкой на SQL - отличное место для настройки.

stephenbayer 16.10.2008 19:15

@ P DBA: Я говорил, что вернет 2 гига? Я просто спрашивал, сможет ли код обработать изменение в таблице, как показано во втором пункте. @SB Вы можете кодировать изменения схемы, большинство разработчиков этого не делают, и что-то ломается. Зачем позволять себе рисковать?

Mark Brady 16.10.2008 19:26

Это зависит от того, что вы подразумеваете под «различием». Существует очевидная разница в синтаксисе, но реальная разница заключается в производительности.

Когда вы говорите SELECT * FROM MyTable, вы указываете механизму запросов SQL вернуть набор данных с все столбцов из этой таблицы, в то время как SELECT ColA, ColB, ColC FROM MyTable сообщает механизму запросов вернуть набор данных с Только ColA, ColB и ColC из таблицы.

Допустим, у вас есть таблица со 100 столбцами, определенная как CHAR [10]. SELECT * вернет 100 столбцов * 10 байтов данных, а SELECT ColA, ColB, ColC вернет 3 столбца * 10 байтов данных. Это огромная разница в размере данных, передаваемых по сети.

Указание списка столбцов также делает более понятным, какие столбцы вас интересуют. Недостатком является то, что если вы добавляете / удаляете столбец из таблицы, вам необходимо убедиться, что список столбцов также обновляется, но я думаю, что это небольшая цена. по сравнению с приростом производительности.

В этом случае разницы в производительности нет. Я полагаю, что вы пропустили ключевую информацию в первой части вопроса: «Когда ColA, ColB и ColC - все столбцы в таблице?» Поскольку ему нужны все столбцы, разницы в производительности нет. Другие вопросы? да.

Pittsburgh DBA 16.10.2008 19:12

@Pittsburgh DBA: Я видел это, но читал по-другому ... поскольку ColA, ColB и ColC - это все столбцы в таблице, а не то, что они были полным набором столбцов в таблице. В любом случае информация в моем ответе по-прежнему актуальна (но в этом случае специфический это промывка).

Scott Dorman 16.10.2008 19:16

выбор каждого столбца лучше, чем просто *, потому что в случае добавления или удаления новой строки вы ДОЛЖНЫ взглянуть на код и посмотреть, что вы делали с полученными данными. Кроме того, это помогает вам лучше понять ваш код и позволяет использовать псевдонимы в качестве имен столбцов (в случае, если вы выполняете соединение таблиц с столбцом, имеющим имя).

Я собираюсь расстроить многих людей из-за меня, но особенно если я добавляю столбцы позже, я обычно предпочитаю использовать таблицу SELECT * FROM. По этой причине меня назвали ленивым, потому что, если я внесу какие-либо изменения в свои таблицы, я бы не хотел отслеживать все сохраненные процессы, которые используют эту таблицу, а просто изменить их в классах уровня доступа к данным в моем приложении. . Бывают случаи, когда я указываю столбцы, но в случае, когда я пытаюсь получить полный «объект» из базы данных, я бы предпочел просто использовать «*». И, да, я знаю, что люди будут меня ненавидеть за это, но это позволило мне быстрее и меньше избавляться от ошибок при добавлении полей в мои приложения.

Я не думаю, что вам нужно слишком защищаться. Это верный ответ на стилистически субъективный вопрос. :)

Greg D 16.10.2008 19:16

«Быстрее» в разработке, конечно. Однако вы можете тратить впустую ввод-вывод почти на каждый из ваших операторов SELECT.

Pittsburgh DBA 16.10.2008 19:23

Я с вами, и я еще не сталкивался с проблемой производительности, которая может быть прослежена до «выбрать *» по сравнению с «выбрать столбец1, столбец2 ...». Я уверен, что это случается, но я предпочитаю иметь дело с этим исключением, когда оно случается, чем защищаться от него, когда мне не нужно в 99% случаев.

JasonS 16.10.2008 19:47

Я тоже с тобой. В определенных обстоятельствах звездочка, очевидно, делает код дешевле в обслуживании (особенно, если у вас есть достойная IDE и / или хорошие соглашения о кодировании), что чаще всего гораздо важнее, чем проблемы, связанные с производительностью.

Yarik 25.10.2009 01:59

Если ваш код полагается на то, что определенные столбцы расположены в определенном порядке, вам необходимо перечислить столбцы. Если нет, то на самом деле не имеет значения, используете ли вы «*» или записываете имена столбцов в операторе select.

Например, если вы вставляете столбец в таблицу.

Возьмите эту таблицу: ColA ColB ColC

У вас может быть запрос:

SELECT *
FROM myTable

Тогда код может быть таким:

rs = executeSql("SELECT * FROM myTable")
while (rs.read())
    Print "Col A" + rs[0]
    Print "Col B" + rs[1]
    Print "Col C" + rs[2]

Если вы добавите столбец между ColB и ColC, запрос не вернет то, что вы ищете.

SELECT * FROM MyTable

select * зависит от порядка столбцов в схеме, поэтому, если вы ссылаетесь на результат, установленный по индексу # коллекции, вы будете смотреть не на тот столбец.

SELECT Col1,Col2,Col3 FROM MyTable

этот запрос даст вам коллекцию, которая остается неизменной с течением времени, но как часто вы все равно меняете порядок столбцов?

Пара вещей:

  • Большое количество людей написали здесь, что рекомендуют не использовать *, и привели несколько веских причин для этих ответов. На данный момент из 10 других ответов только один не рекомендует перечислять столбцы.
  • Люди часто делают исключения из этого правила при публикации сообщений на таких сайтах, как StackOverflow, потому что они часто не знают, какие столбцы находятся в вашей таблице или важны для вашего запроса. По этой причине вы увидите много кода здесь и в других местах в Интернете, который использует синтаксис *, даже если автор сообщения старается избегать его в своем собственном коде.

У проблемы есть две стороны: явная спецификация столбца дает лучшую производительность при добавлении новых столбцов, но * спецификация не требует обслуживания при добавлении новых столбцов.

Что использовать, зависит от того, какие столбцы вы ожидаете добавить в таблицу и в чем суть запроса.

Если вы используете свою таблицу в качестве резервного хранилища для объекта (что кажется вероятным в случае LINQ-to-SQL), вы, вероятно, захотите, чтобы любые новые столбцы, добавленные в эту таблицу, были включены в ваш объект, и наоборот. Вы поддерживаете их параллельно. По этой причине для этого случая правильная спецификация * в предложении SELECT. Явная спецификация предоставит вам дополнительную поддержку каждый раз, когда что-то изменится, и ошибку, если вы не обновите список полей правильно.

Если запрос будет возвращать много записей, вам, вероятно, будет лучше с явной спецификацией по соображениям производительности.

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

Пример того, почему вы никогда (imho) не должны использовать SELECT *. Это не относится к MSSQL, а скорее к MySQL. Версии до 5.0.12 возвращали столбцы из определенных типов объединений нестандартным образом. Конечно, если ваши запросы определяют, какие столбцы вам нужны и в каком порядке, у вас нет проблем. Представьте себе удовольствие, если они этого не сделают.

(Одно возможное исключение: ваш запрос выбирает только одну таблицу и, вы определяете столбцы на выбранном вами языке программирования по имени, а не по положению.)

Использование "SELECT *" оптимизирует набор текста программистом. Вот и все. Это единственное преимущество.

Другие вопросы по теме