Я использую 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 представляют каждый столбец в таблице?» для ясности.


Когда вы выбираете каждое поле по отдельности, становится более ясно, какие именно поля выбираются.
Как правило, лучше быть явным, поэтому Select col1, col2 from Table лучше. Причина в том, что в какой-то момент в эту таблицу может быть добавлен дополнительный столбец, что приведет к возврату ненужных данных из запроса.
Однако это не жесткое правило.
Во многих случаях это также вызывает сбой зависимого кода. Это особенно верно в средах с ленивыми разработчиками, которые не используют списки столбцов в операторах INSERT.
однако в некоторых случаях явное выражение означает, что вам, возможно, придется изменить каждый отдельный код, который использует таблицу, поскольку вы делать хотите, чтобы новый столбец отображался почти везде. Хотя вам часто все еще необходимо изменить код представления, простой переход с * все равно сократит работу вдвое в этих случаях. Все зависит от того, что вы делаете, и каковы ваши планы на будущее.
с точки зрения разработчиков, это не так хорошо, потому что если вам придется изменить или удалить имя столбца, это вызовет панику, потому что вам придется менять его везде. но, сэр @swilliams, есть ли у него какие-то преимущества в производительности?
1) Второй вариант более четко определяет, какие столбцы возвращаются. Тогда значение второго - это то, насколько вы цените, зная, какие столбцы возвращаются.
2) Это подразумевает, что возвращается потенциально меньше данных, когда столбцов больше, чем явно используемых.
3) Если вы измените таблицу, добавив новый столбец, первый запрос изменится, а второй - нет. Если у вас есть код типа «для всех возвращаемых столбцов сделать ...», то результаты изменятся, если вы используете первый, но не второй.
Некоторые причины не использовать первого оператора (выберите *):
Я не против твоего ответа. но большинство баз данных используют отдельные вызовы для загрузки типов Large Object(BLOB), когда для набора результатов запрашивается соответствующий метод получения. Таким образом, производительность снижается только тогда, когда вы действительно хотите, чтобы эти столбцы были прочитаны.
Вы должны указать явный список столбцов. SELECT * вернет больше столбцов, чем вам нужно, для создания большего количества операций ввода-вывода и сетевого трафика, но, что более важно, может потребоваться дополнительный поиск, даже если существует некластеризованный покрывающий индекс (на SQL Server).
Да! Это лучшая причина для ясности - индексы покрытия.
Принятый ответ, кажется, удовлетворяет [неправильные] представления большинства людей о разнице между * и col1, col2, col3.
Беглый взгляд на план выполнения запроса показывает, что запросы совпадают.
Общее практическое правило состоит в том, что вы захотите ограничить свои запросы только теми полями, которые вам нужно вернуть.
Это хорошо для прямой совместимости.
Когда вы используете
SELECT * FROM myTable
а в «myTable» 3 столбца. Вы получите те же результаты, что и
SELECT Column1, Column2, Column3 FROM myTable
Но если вы добавите новый столбец в будущем, вы получите другие результаты.
Конечно, если вы измените имя одного из существующих столбцов, в первом случае вы получите результат, а во втором случае вы получите ошибку (я думаю, это правильное поведение приложения).
Я не уверен, что нарушение при будущих изменениях - это определение прямой совместимости.
Я думаю, что аргументы TcKs заключаются в том, что взломать лучше, чем делать вид, что работает (но не работает).
Я согласен, приложение должно сломаться, если вы переименуете столбец и получите доступ к результатам по имени столбца. Использование * ничуть не лучше для защиты от переименования, если вы по-прежнему получаете доступ к результатам по имени столбца, а не по индексу.
@Greg D Да, именно это я и имел в виду.
Для LinqToSql, если вы планируете изменить эти записи позже, вы должны вытащить всю запись в память.
SELECT * - это плохая практика в большинстве случаев.
Это ошибка, которая ждет своего часа.
"SELECT *" не вернет 2 гига, так что это не имеет значения. Это добавление столбцов, влияющих на зависимый код, наряду с удобочитаемостью и ясностью, что действительно имеет значение.
Я в основном согласен, за исключением части ошибки. Я обнаружил, что смог избежать ошибок, просто получив всю строку и имея только одно место (класс уровня доступа к данным) для обработки этих данных. Я обычно решаю возможные проблемы там. классы модели данных со ссылкой на SQL - отличное место для настройки.
@ P DBA: Я говорил, что вернет 2 гига? Я просто спрашивал, сможет ли код обработать изменение в таблице, как показано во втором пункте. @SB Вы можете кодировать изменения схемы, большинство разработчиков этого не делают, и что-то ломается. Зачем позволять себе рисковать?
Это зависит от того, что вы подразумеваете под «различием». Существует очевидная разница в синтаксисе, но реальная разница заключается в производительности.
Когда вы говорите 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: Я видел это, но читал по-другому ... поскольку ColA, ColB и ColC - это все столбцы в таблице, а не то, что они были полным набором столбцов в таблице. В любом случае информация в моем ответе по-прежнему актуальна (но в этом случае специфический это промывка).
выбор каждого столбца лучше, чем просто *, потому что в случае добавления или удаления новой строки вы ДОЛЖНЫ взглянуть на код и посмотреть, что вы делали с полученными данными. Кроме того, это помогает вам лучше понять ваш код и позволяет использовать псевдонимы в качестве имен столбцов (в случае, если вы выполняете соединение таблиц с столбцом, имеющим имя).
Я собираюсь расстроить многих людей из-за меня, но особенно если я добавляю столбцы позже, я обычно предпочитаю использовать таблицу SELECT * FROM. По этой причине меня назвали ленивым, потому что, если я внесу какие-либо изменения в свои таблицы, я бы не хотел отслеживать все сохраненные процессы, которые используют эту таблицу, а просто изменить их в классах уровня доступа к данным в моем приложении. . Бывают случаи, когда я указываю столбцы, но в случае, когда я пытаюсь получить полный «объект» из базы данных, я бы предпочел просто использовать «*». И, да, я знаю, что люди будут меня ненавидеть за это, но это позволило мне быстрее и меньше избавляться от ошибок при добавлении полей в мои приложения.
Я не думаю, что вам нужно слишком защищаться. Это верный ответ на стилистически субъективный вопрос. :)
«Быстрее» в разработке, конечно. Однако вы можете тратить впустую ввод-вывод почти на каждый из ваших операторов SELECT.
Я с вами, и я еще не сталкивался с проблемой производительности, которая может быть прослежена до «выбрать *» по сравнению с «выбрать столбец1, столбец2 ...». Я уверен, что это случается, но я предпочитаю иметь дело с этим исключением, когда оно случается, чем защищаться от него, когда мне не нужно в 99% случаев.
Я тоже с тобой. В определенных обстоятельствах звездочка, очевидно, делает код дешевле в обслуживании (особенно, если у вас есть достойная IDE и / или хорошие соглашения о кодировании), что чаще всего гораздо важнее, чем проблемы, связанные с производительностью.
Если ваш код полагается на то, что определенные столбцы расположены в определенном порядке, вам необходимо перечислить столбцы. Если нет, то на самом деле не имеет значения, используете ли вы «*» или записываете имена столбцов в операторе 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
этот запрос даст вам коллекцию, которая остается неизменной с течением времени, но как часто вы все равно меняете порядок столбцов?
Пара вещей:
У проблемы есть две стороны: явная спецификация столбца дает лучшую производительность при добавлении новых столбцов, но * спецификация не требует обслуживания при добавлении новых столбцов.
Что использовать, зависит от того, какие столбцы вы ожидаете добавить в таблицу и в чем суть запроса.
Если вы используете свою таблицу в качестве резервного хранилища для объекта (что кажется вероятным в случае LINQ-to-SQL), вы, вероятно, захотите, чтобы любые новые столбцы, добавленные в эту таблицу, были включены в ваш объект, и наоборот. Вы поддерживаете их параллельно. По этой причине для этого случая правильная спецификация * в предложении SELECT. Явная спецификация предоставит вам дополнительную поддержку каждый раз, когда что-то изменится, и ошибку, если вы не обновите список полей правильно.
Если запрос будет возвращать много записей, вам, вероятно, будет лучше с явной спецификацией по соображениям производительности.
Если оба утверждения верны, рассмотрите возможность использования двух разных запросов.
Пример того, почему вы никогда (imho) не должны использовать SELECT *. Это не относится к MSSQL, а скорее к MySQL. Версии до 5.0.12 возвращали столбцы из определенных типов объединений нестандартным образом. Конечно, если ваши запросы определяют, какие столбцы вам нужны и в каком порядке, у вас нет проблем. Представьте себе удовольствие, если они этого не сделают.
(Одно возможное исключение: ваш запрос выбирает только одну таблицу и, вы определяете столбцы на выбранном вами языке программирования по имени, а не по положению.)
Использование "SELECT *" оптимизирует набор текста программистом. Вот и все. Это единственное преимущество.
См. Также: stackoverflow.com/questions/65512/…