Я слышал, что SELECT *, как правило, является плохой практикой при написании команд SQL, потому что он более эффективен для столбцов SELECT, которые вам особенно нужны.
Если мне нужно SELECT для каждого столбца в таблице, следует ли мне использовать
SELECT * FROM TABLE
или же
SELECT column1, colum2, column3, etc. FROM TABLE
Имеет ли значение в этом случае эффективность? Я бы подумал, что SELECT * будет более оптимальным внутренне, если вам действительно нужны все данные, но я говорю это без реального понимания базы данных.
Мне любопытно узнать, что в этом случае лучше всего.
Обновлено: Я, вероятно, должен указать, что единственная ситуация, когда я действительно хотел бы хотеть сделать SELECT *, - это когда я выбираю данные из одной таблицы, где я знаю, что все столбцы всегда должны быть извлечены, даже когда добавляются новые столбцы.
Однако, учитывая ответы, которые я видел, это все еще кажется плохой идеей, и SELECT * никогда не должен использоваться по гораздо более техническим причинам, о которых я когда-либо думал.
см .: stackoverflow.com/questions/262450/…stackoverflow.com/questions/65512/…stackoverflow.com/questions/413819/select-exceptstackoverflow.com/questions/208925/…stackoverflow.com/questions/487578/…stackoverflow.com/questions/1433971/…
Да, это дубликат большинства из них.


определенно определяя столбцы, потому что SQL Server не будет выполнять поиск по столбцам, чтобы извлечь их. Если вы определяете столбцы, SQL может пропустить этот шаг.
Это: 1) не имеет отношения к делу, потому что SQL Server должен ссылаться на схему таблицы в любом случае (для проверки имен столбцов или для поиска известных допустимых имен столбцов) 2) не имеет отношения к заданному вопросу, где указываются все столбцы. Единственная проблема, КОТОРАЯ ЗАПРОСИЛАСЬ, - это хрупкость с изменениями схемы.
Проголосовали против, потому что он должен проверять столбцы в любом случае.
Всегда лучше указывать нужные столбцы, если вы однажды подумаете об этом, SQL не обязательно будет думать «wtf is *» каждый раз, когда вы запрашиваете. Вдобавок ко всему, кто-то позже может добавить в таблицу столбцы, которые вам действительно не нужны в вашем запросе, и вам будет лучше в этом случае, указав все свои столбцы.
Это неверно: SQL-сервер должен по-прежнему анализировать каждый столбец и видеть, существует ли он в каталогах, тогда как знает, что "*", делает (и да, * расширяется до всех столбцов). В любом случае для СУБД тривиально легко выполнить любой из них (если у вас нет 24000 столбцов), поэтому я уверен, что в любом случае это то же самое.
Я думаю, что лучший момент, который многие отсутствуют, и, к сожалению, этот ответ касается только во вторую очередь, заключается в том, что если произойдет изменение схемы / таблицы (то есть добавлены новые столбцы), это не сломает ничего.
Это полная стирка, поскольку поиск столбцов для расширения * аналогичен проверке предоставленных имен столбцов.
Одна из причин, по которой выбор определенных столбцов лучше, заключается в том, что это увеличивает вероятность того, что SQL Server может получить доступ к данным из индексов, а не запрашивать данные таблицы.
Вот пост, который я написал об этом: Настоящая причина, по которой запросы выбора - это плохое покрытие индекса
Это также менее уязвимо для изменений, поскольку любой код, который потребляет данные, будет получать ту же структуру данных, независимо от изменений, которые вы внесете в схему таблицы в будущем.
+1 за это. Если все упомянутые столбцы существуют в одном индексе («индекс покрытия»), вы попали в золотую медаль.
это не ответ на его вопрос - «Если мне нужно ВЫБРАТЬ каждый столбец в таблице, ...» - в этом случае * vs col1, .., coln не имеет значения (но это ДЕЙСТВИТЕЛЬНО для времени программиста, поскольку * короче!).
Это все еще имеет значение, потому что список выбора - это форма контракта, особенно если SQL находится в хранимой процедуре.
Хотя то, что говорит Джон, совершенно правильно и очень обоснованно, я должен согласиться с тем, что ЗАДАВАЕМЫЙ вопрос касается того, запрашивают ли они уже все столбцы. Из-за этой части вопроса настоящая проблема заключается в нестабильности перед лицом изменений схемы.
По моему опыту, при изменении схемы все еще приходится «перекомпилировать» представления. Причина в том, что столбцы преобразуются в числа, поэтому, хотя имена остаются прежними, числа больше не совпадают. Я знаю это, потому что я получал сообщения об ошибках, указывающие на это, и простая перекомпиляция решила проблему. Следовательно, в случае упоминания OP, * было бы лучше.
@Jon Galloway, не могли бы вы объяснить / уточнить следующую часть вашей ссылки "Хотя SQL Server в основном использует индексы для поиска ваших данных, если индекс содержит все столбцы, которые вы запрашиваете, ему даже не нужно смотреть в таблицу . Эта концепция известна как индексное покрытие ".
@MattRogish, сэр, вы правильно поняли, есть ли разница в производительности между этими двумя методами (* vs all_column_names), когда у нас тысячи строк и мы выполняем SELECT с индексом (в предложении WHERE) ??
С точки зрения производительности, SELECT с определенными столбцами может быть быстрее (нет необходимости читать все данные). Если ваш запрос действительно использует ВСЕ столбцы, все же предпочтительнее выбрать SELECT с явными параметрами. Любая разница в скорости будет практически незаметной и практически постоянной. Однажды ваша схема изменится, и это хорошая страховка для предотвращения связанных с этим проблем.
Вы ошибаетесь насчет незаметности, поскольку из проверок, которые я провел с несколькими БД, было ясно, что выбор каждого столбца, даже если все они, намного быстрее. В некоторых случаях это было в три раза быстрее.
Select одинаково эффективен (с точки зрения скорости), если вы используете * или столбцы.
Разница в памяти, а не в скорости. Когда вы выбираете несколько столбцов, SQL Server должен выделить пространство памяти для обслуживания запроса, включая все данные для всех запрашиваемых столбцов, даже если вы используете только один из них.
Что имеет значение с точки зрения производительности, так это план исключений, который, в свою очередь, сильно зависит от вашего предложения WHERE и количества JOIN, OUTER JOIN и т. д.
Для вашего вопроса просто используйте SELECT *. Если вам нужны все столбцы, разницы в производительности нет.
Это зависит от версии вашего сервера БД, но современные версии SQL могут кэшировать план в любом случае. Я бы сказал, что используйте то, что наиболее удобно для вашего кода доступа к данным.
Абсолютно определяйте столбцы, которые вы хотите ВЫБРАТЬ каждый раз. Нет причин не делать этого, и улучшение производительности того стоит.
Им никогда не следовало давать возможность «ВЫБРАТЬ *»
Если вам нужен каждый столбец, просто используйте SELECT *, но помните, что порядок потенциально может измениться, поэтому, когда вы потребляете результаты, обращайтесь к ним по имени, а не по индексу.
Я бы проигнорировал комментарии о том, как * нужно получить список - шансы на синтаксический анализ и проверку именованных столбцов равны времени обработки, если не больше. Не оптимизируйте преждевременно ;-)
Одна из причин, по которой лучше всего точно указать, какие столбцы вам нужны, - это возможные будущие изменения в структуре таблицы.
Если вы читаете данные вручную, используя подход на основе индекса для заполнения структуры данных результатами вашего запроса, то в будущем, когда вы добавляете / удаляете столбец, у вас будут головные боли, пытаясь выяснить, что пошло не так.
Что касается того, что быстрее, я полагаюсь на других, чтобы узнать их мнение.
С точки зрения эффективности исполнения я не заметил существенной разницы. Но для удобства программистов я бы написал названия полей, потому что
Проблема с "select *" заключается в возможности переноса данных, которые вам действительно не нужны. Во время фактического запроса к базе данных выбранные столбцы на самом деле не добавляют к вычислениям. Что действительно «тяжело», так это транспортировка данных обратно вашему клиенту, и любой столбец, который вам на самом деле не нужен, просто тратит впустую пропускную способность сети и увеличивает время, которое вы ждете, чтобы получить ответ от вашего запроса.
Даже если вы используете все столбцы, полученные из «select * ...», это только сейчас. Если в будущем вы измените макет таблицы / представления и добавите больше столбцов, вы начнете вносить их в свой выбор, даже если они вам не нужны.
Еще один момент, когда оператор «select *» плох, - это создание представления. Если вы создаете представление с помощью «select *», а затем добавляете столбцы в свою таблицу, определение представления и возвращаемые данные не будут совпадать, и вам придется перекомпилировать представления, чтобы они снова заработали.
Я знаю, что писать «select *» заманчиво, потому что я действительно не люблю вручную указывать все поля в моих запросах, но когда ваша система начнет развиваться, вы увидите, что стоит потратить это дополнительное время / усилия по указанию полей вместо того, чтобы тратить гораздо больше времени и усилий на устранение ошибок в ваших представлениях или оптимизацию вашего приложения.
Пункт о ВЗГЛЯДАХ очень важен. Мало того, что вы не получите все столбцы, если вы добавите столбцы в таблицу (несмотря на то, что вы думаете о *), но они могут даже не соответствовать реальному макету таблицы.
Хотя явное перечисление столбцов полезно для производительности, не сходите с ума.
Поэтому, если вы используете все данные, попробуйте для простоты SELECT * (представьте, что у вас много столбцов и выполнение запроса JOIN ... может быть ужасным). Потом - замерь. Сравните с запросом с явно указанными именами столбцов.
Не спекулируйте на производительности, измерить это!
Явное перечисление больше всего помогает, когда у вас есть столбец, содержащий большие данные (например, текст сообщения или статьи), и он не нужен в данном запросе. Затем, не возвращая его в своем ответе, сервер БД может сэкономить время, полосу пропускания и пропускную способность диска. Результат вашего запроса также будет меньше, что хорошо для любого кеша запросов.
эй, будь практичным. используйте select * при создании прототипа и выберите определенные столбцы при реализации и развертывании. с точки зрения плана выполнения, оба они относительно идентичны в современных системах. однако выбор определенных столбцов ограничивает объем данных, которые должны быть извлечены с диска, сохранены в памяти и отправлены по сети.
в конечном итоге лучший план - выбрать определенные столбцы.
Указание списка столбцов - лучший вариант обычно, потому что ваше приложение не пострадает, если кто-то добавит / вставит столбец в таблицу.
Также имейте в виду изменения. Сегодня Select * выбирает только те столбцы, которые вам нужны, но завтра он также может выбрать тот столбец varbinary (MAX), который я только что добавил, не сообщая вам, и теперь вы также получаете все 3,18 гигабайт двоичных данных, которые не были в таблице вчера.
Давайте подумаем, что быстрее. Если вы можете выбрать только те данные, которые вам нужны, это будет быстрее. Однако при тестировании вы можете извлечь все данные, чтобы определить, какие данные можно отфильтровать в зависимости от потребностей бизнеса.
Можно значительно повысить производительность, если ограничить количество возвращаемых столбцов, если записи передаются через Интернет.
Вам не на чем основывать термин «огромный». Без замера нельзя оценить размер.
У меня есть таблица с 10 записями. Значения таблиц никогда не меняются, значит, о производительности говорить не приходится. Также не будет воссоздан план выполнения.
НЕ быстрее использовать явные имена полей по сравнению с *, тогда и только тогда, когда вам нужно получить данные для всех полей.
Ваше клиентское программное обеспечение не должно зависеть от порядка возвращаемых полей, так что это тоже нонсенс.
И возможно (хотя маловероятно), что вам нужно получить все поля с помощью *, потому что вы еще не знаете, какие поля существуют (подумайте об очень динамической структуре базы данных).
Еще один недостаток использования явных имен полей заключается в том, что если их много и они длинные, это затрудняет чтение кода и / или журнала запросов.
Итак, правило должно быть таким: если вам нужны все поля, используйте *, если вам нужно только подмножество, назовите их явно.
Что ж, это действительно зависит от ваших показателей и цели:
Как правило, когда мне нужно выбрать все столбцы, я бы использовал "select *", если только у меня не было очень конкретной причины поступить иначе (плюс, я думаю, что это быстрее для таблиц с большим количеством столбцов)
И последнее, но не менее важное: как вы хотите, чтобы добавление или удаление столбца в таблице повлияло на ваш код или его обслуживание?
Как и в случае с большинством проблем, это зависит от того, чего вы хотите достичь. Если вы хотите создать сетку БД, которая позволит использовать все столбцы в любой таблице, то ответом будет «Выбрать *». Однако, если вам понадобятся только определенные столбцы, а добавление или удаление столбцов из запроса выполняется нечасто, укажите их индивидуально.
Это также зависит от количества данных, которые вы хотите передать с сервера. Если один из столбцов определен как памятка, графика, большой двоичный объект и т. д., И вам не нужен этот столбец, вам лучше не использовать «Выбрать *», иначе вы получите целую кучу данных, которых у вас нет. хотите, и ваша производительность может пострадать.
Основное различие между ними - количество данных, передаваемых туда и обратно. Любые аргументы о разнице во времени в корне ошибочны в том, что "select *" и "select col1, ..., colN" приводят к одинаковому объему относительной работы, выполняемой механизмом БД. Однако передача 15 столбцов в строке по сравнению с 5 столбцами в строке - это разница в 10 столбцов.
Если вас беспокоит скорость, убедитесь, что вы используете подготовленные операторы. В противном случае я убежден, что изменения - это то, от чего вы себя защищаете.
/ Аллан
Я всегда рекомендую указывать нужные столбцы на тот случай, если ваша схема изменится и дополнительный столбец вам не понадобится.
Кроме того, уточняйте имена столбцов с именем таблицы. Это очень важно, если запрос содержит соединения. Без квалификаций таблицы может быть трудно запомнить, какой столбец из какой таблицы, а добавление столбца с таким же именем в одну из других таблиц может нарушить ваш запрос.
Используйте определенные имена полей, чтобы, если кто-то изменит таблицу на вас, вы не получите неожиданных результатов. По теме: ВСЕГДА указывайте имена полей при вставке, поэтому, если вам понадобится добавить столбец позже, вам не нужно возвращаться и исправлять свою программу и одновременно изменять базу данных в производственном выпуске.
Я считаю, что перечисление имен столбцов особенно важно, если с кодом будут работать другие разработчики или если база данных может измениться, чтобы вы всегда получали согласованные данные.
Важность эффективности во многом зависит от размера ваших производственных наборов данных (и скорости их роста). Если ваши наборы данных не будут такими большими и они не будут расти так быстро, выбор отдельных столбцов может не дать большого преимущества в производительности.
При больших наборах данных и более высоких темпах роста данных преимущество в производительности становится все более и более важным.
Чтобы графически увидеть, есть ли разница, я бы предложил использовать анализатор запросов, чтобы увидеть план выполнения запроса для SELECT * и эквивалентного SELECT col1, col2 и т. д. Это должно сказать вам, какой из двух запросов более эффективен. Вы также можете сгенерировать некоторые тестовые данные разного объема, чтобы узнать время.
В дополнение к сказанному всеми, если все ваши столбцы, которые вы выбираете, включены в индекс, ваш набор результатов будет извлечен из индекса, а не искать дополнительные данные из SQL.
Учитывая спецификацию ваш, что вы находятся выбираете все столбцы, есть небольшая разница на данный момент. Однако следует понимать, что схемы базы данных действительно меняются. Если вы используете SELECT *, вы собираетесь добавить любые новые столбцы в таблицу, даже если, по всей вероятности, ваш код не готов использовать или представлять эти новые данные. Это означает, что вы подвергаете свою систему неожиданным изменениям производительности и функциональности.
Возможно, вы захотите отклонить это как незначительные затраты, но помните, что столбцы, которые вам не нужны, все равно должны быть:
Пункт №1 имеет много скрытых затрат, включая устранение некоторого потенциального покрывающего индекса, вызывающее загрузку страниц данных (и перегрузку кэша сервера), возникновение блокировок строк / страниц / таблиц, которых в противном случае можно было бы избежать.
Уравновесьте это с потенциальной экономией при указании столбцов по сравнению с *, и единственная потенциальная экономия:
Для пункта 1 реальность такова, что вы собираетесь добавить / изменить код для использования любого нового столбца, который вы все равно можете добавить, так что это промывка.
Для пункта 2 разницы редко бывает достаточно, чтобы подтолкнуть вас к другому размеру пакета или количеству сетевых пакетов. Если вы дойдете до того, что время передачи оператора SQL является преобладающей проблемой, вам, вероятно, сначала нужно уменьшить частоту запросов.
Для пункта 3 нет никакой экономии, поскольку расширение * должно произойти в любом случае, что в любом случае означает обращение к схеме таблицы (таблиц). На самом деле перечисление столбцов потребует таких же затрат, потому что они должны быть проверены на соответствие схеме. Другими словами, это полная стирка.
Для элемента 4, когда вы указываете определенные столбцы, ваш кеш плана запроса может увеличиться, но Только, если вы имеете дело с разными наборами столбцов (это не то, что вы указали). В этом случае вы хочу различных записей кэша, потому что вам нужны разные планы по мере необходимости.
Итак, все сводится к тому, как вы задали вопрос, к устойчивости проблемы перед лицом возможных модификаций схемы. Если вы записываете эту схему в ПЗУ (такое бывает), то * вполне приемлемо.
Однако мой общий совет заключается в том, что вы должны выбирать только те столбцы, которые вам нужны, что означает, что иногда будет выглядеть так, как будто вы запрашиваете все из них, но администраторы баз данных и эволюция схемы означают, что могут появиться некоторые новые столбцы, которые могут сильно повлиять на запрос. .
Я советую вам ВСЕГДА ВЫБИРАЙТЕ определенные столбцы. Помните, что вы получаете хорошие результаты в том, что делаете, снова и снова, поэтому просто возьмите за привычку делать это правильно.
Если вам интересно, почему схема может измениться без изменения кода, подумайте о журналах аудита, датах вступления в силу / истечении срока действия и других подобных вещах, которые администраторы баз данных добавляют систематически для решения проблем соответствия. Еще один источник скрытых изменений - денормализация производительности где-то еще в системе или в пользовательских полях.
«реальность такова, что вы собираетесь добавить / изменить код, чтобы использовать любой новый столбец, который вы могли бы добавить, так что это промывка». -Только если вы вручную читаете каждый столбец по имени в своем коде. Если вы используете автоматическое сопоставление, это не так, и эта проблема становится значительной.
Для производительности особенно важно не использовать select *, когда у вас есть соединение, потому что по определению как минимум два поля содержат одни и те же данные. Вы не хотите тратить ресурсы сети на отправку ненужных данных с сервера базы данных в приложение или веб-сервер. Может показаться, что использовать select * проще, но это плохая практика. Поскольку легко перетащить имена столбцов в запрос, просто сделайте это.
Другая проблема, которая возникает при использовании select *, заключается в том, что есть идиоты, которые предпочитают добавлять новые поля в середину таблицы (всегда плохая практика), если вы используете select * в качестве основы для вставки, тогда внезапно ваш порядок столбцов может быть неправильно, и вы можете попытаться вставить номер социального страхования в гонорар (сумма денег, которую докладчик может получить за выбор неслучайного примера), что может быть очень плохим фактором для целостности данных. Даже если выбор не является вставкой, заказчику будет плохо, если данные в отчете или на веб-странице внезапно окажутся в том же порядке, что и они.
Я думаю, что нет никаких обстоятельств, когда использование select * предпочтительнее использования списка столбцов. Вы можете подумать, что его легче поддерживать, но на самом деле это не так, и это приведет к тому, что ваше приложение станет медленнее без причины, когда поля, которые вам не нужны, добавляются в таблицы. Вам также придется столкнуться с проблемой исправления вещей, которые не сломались бы, если бы вы использовали список столбцов, поэтому время, которое вы экономите, не добавляя столбец, тратится на это.
Бывают случаи, когда SELECT * подходит для целей обслуживания, но в целом этого следует избегать.
Это особые случаи, такие как представления или хранимые процедуры, когда вы хотите, чтобы изменения в базовых таблицах распространялись без необходимости переходить и изменять каждое представление и хранимую процедуру, которая использует таблицу. Даже в этом случае это может вызвать проблемы, как в случае, когда у вас есть два соединенных представления. Одна базовая таблица изменяется, и теперь представление неоднозначно, поскольку в обеих таблицах есть столбец с одинаковым именем. (Обратите внимание, что это может произойти в любое время, когда вы не квалифицируете все свои столбцы с префиксами таблиц). Даже с префиксами, если у вас есть такая конструкция, как:
ВЫБЕРИТЕ A., Б. - у вас могут возникнуть проблемы, когда у клиента возникнут трудности с выбором правильного поля.
В общем, я не использую SELECT *, если я не принимаю осознанное дизайнерское решение и не рассчитываю, что связанные с этим риски будут низкими.
Для прямого запроса БД (например, в приглашении sqlplus или через инструмент администрирования БД) обычно подходит выбор * - это избавляет вас от необходимости записывать все столбцы.
С другой стороны, в коде приложения столбцы лучше пронумеровать. Это дает несколько преимуществ:
Определенно быстрее указать имена столбцов - для сервера. Но если
тогда вам лучше придерживаться SELECT *. В нашей структуре интенсивное использование SELECT * позволяет нам ввести новое поле управляемого содержимого веб-сайта в таблицу, предоставляя ей все преимущества CMS (управление версиями, рабочий процесс / утверждения и т. д.), При этом касаясь кода только пара баллов вместо пары десятков баллов.
Я знаю, что гуру БД возненавидят меня за это - давай, проголосуй за меня - но в моем мире времени разработчика мало, а циклов ЦП много, поэтому я корректирую соответственно то, что я сохраняю, и то, что трачу впустую.
Это также значительно упрощает использование ORM. Когда запросы создаются путем передачи объекта построения запроса, не обязательно знать, какие столбцы требуются для каких других частей кода (проверки разрешений, что у вас есть). Таким образом, чтобы ограничить количество столбцов, нужно было бы исследовать каждый раз, когда нужно написать запрос. Это бессмысленно, ИМО. Когда запросы оказываются медленными (журналы!), Их можно улучшить.
SELECT * необходим, если нужно получить метаданные, такие как количество столбцов.
Я вижу, что некоторые люди думают, что определение столбцов занимает гораздо больше времени. Поскольку вы можете перетащить список столбцов из обозревателя объектов, может потребоваться дополнительная минута, чтобы указать столбцы (например, если у вас много столбцов и вам нужно потратить некоторое время на их размещение в отдельных строках) в запросе. Почему люди думают, что это занимает так много времени?
Меня за это хлопнут, но я делаю выбор *, потому что почти все мои данные извлекаются из представлений SQL Server, которые предварительно объединяют необходимые значения из нескольких таблиц в одно представление с легким доступом.
Затем мне нужны все столбцы из представления, которые не изменятся при добавлении новых полей в базовые таблицы. Это дает мне дополнительное преимущество, так как я могу изменить источник данных. Поле A в представлении может быть вычислено за один раз, а затем я могу изменить его на статический. В любом случае View поставляет мне FieldA.
Прелесть этого в том, что он позволяет моему слою данных получать наборы данных. Затем он передает их моему BL, который затем может создавать из них объекты. Мое основное приложение знает только объекты и взаимодействует с ними. Я даже позволяю своим объектам самосоздавать, когда передаю строку данных.
Конечно, я единственный разработчик, так что это тоже помогает :)
Результат слишком велик. Генерация и отправка результата от механизма SQL клиенту выполняется медленно.
Клиентская сторона, являясь общей средой программирования, не предназначена и не должна быть предназначена для фильтрации и обработки результатов (например, предложение WHERE, предложение ORDER), поскольку количество строк может быть огромным (например, десятки миллионов строк).
Так что, если бы вам действительно нужно было использовать все разные столбцы, это было бы хорошо ... и если ваша база данных и приложение снова находятся на одном сервере, это не имеет большого значения?
@Ankur: Даже на одном сервере есть стоимость передачи данных через интерфейс базы данных.
Вам следует выбрать только те столбцы, которые вам нужны. Даже если вам нужны все столбцы, все равно лучше перечислить имена столбцов, чтобы серверу sql не приходилось запрашивать столбцы в системной таблице.
Кроме того, ваше приложение может сломаться, если кто-то добавит столбцы в таблицу. Ваша программа также получит столбцы, которых она не ожидала, и может не знать, как их обрабатывать.
Кроме того, если в таблице есть двоичный столбец, запрос будет намного медленнее и будет использовать больше сетевых ресурсов.
Ага, так что, используя *, вы добавляете дополнительную работу для БД. Хорошо, это одна из причин, о которой я не подумал.
+1 за риски взлома / раннего обнаружения ошибок. Я думаю, что обсуждение эффективности справедливо, но YAGNI.
Разве серверу SQL не нужно было проверять или проверять, находится ли «col1» в указанной таблице, то есть запрашивать системную таблицу?
Самый большой удар по производительности, вероятно, связан с индексацией. Если столбец, который вы ищете, является частью индекса, используемого для поиска данных, сервер будет извлекать данные прямо здесь, если вы сделаете выбор *, ему, скорее всего, придется выполнить то, что называется поиском по закладкам, что требует дополнительных отсканируйте, чтобы найти остальные базовые данные, которые могут вам даже не понадобиться.
@Patrick - Точнее. Множество веских причин избегать *, но это не одна из них.
Вам действительно следует выбирать только нужные поля и только необходимое количество, т.е.
SELECT Field1, Field2 FROM SomeTable WHERE --(constraints)
Вне базы данных динамические запросы подвержены риску внедрения атак и искажения данных. Обычно это обходится с помощью хранимых процедур или параметризованных запросов. Кроме того (хотя на самом деле это не такая уж большая проблема) сервер должен генерировать план выполнения каждый раз, когда выполняется динамический запрос.
«сервер должен генерировать план выполнения каждый раз, когда выполняется динамический запрос», что, как я полагаю, замедляет запрос. Спасибо.
Проблемы с производительностью при использовании динамического sql, вероятно, будут реализованы только в сценариях с очень высокой нагрузкой, Sql Server довольно хорошо справляется с эффективным управлением планами запросов.
SELECT *мог бы подойдет, если вам действительно нужны все столбцы, но вы все равно должны перечислить их все по отдельности. Вы, конечно, не должны выбирать все строки из таблицы, даже если приложение и БД находятся на одном сервере или в сети. Перенос всех строк займет время, особенно если количество строк растет. У вас должно быть хотя бы предложение where для фильтрации результатов и / или страницы результатов, чтобы выбрать только подмножество строк, которые необходимо отобразить. Существует несколько инструментов ORM в зависимости от языка приложения, который вы используете для помощи в запросах и разбиении на страницы нужного вам подмножества данных. Например, в .NET Linq to SQL, Entity Framework и nHibernate все помогут вам в этом.
Присвоение имени каждому столбцу, который вы ожидаете получить в своем приложении, также гарантирует, что ваше приложение не сломается, если кто-то изменит таблицу, пока ваши столбцы все еще присутствуют (в любом порядке).
SELECT * - плохая практика, даже если запрос не отправляется по сети.
Конечно, для небольшой и простой системы все это не имеет большого значения.
select * - это плохая вещь по четырем основным причинам:
Самая важная практическая причина заключается в том, что он заставляет пользователя волшебным образом узнать порядок, в котором будут возвращены столбцы. Лучше быть явным, что также защитит вас от изменения таблицы, которая красиво переходит в ...
Если имя столбца, которое вы используете, изменяется, лучше поймать его на ранней стадии (в момент вызова SQL), чем когда вы пытаетесь использовать столбец, который больше не существует (или его имя было изменено и т. д.) )
Перечисление имен столбцов делает ваш код более самодокументированным и, вероятно, более читаемым.
Если вы выполняете передачу по сети (или даже если это не так), столбцы, которые вам не нужны, просто бесполезны.
«Наиболее важной практической причиной является то, что он заставляет пользователя волшебным образом узнать порядок, в котором будут возвращены столбцы». Я не понимаю, в чем проблема. В любом современном клиенте БД вы читаете столбцы по имени, а не по порядку.
Я обычно запускаю свой SQL через интерфейс C, поэтому я не знаю, каково состояние дел в «клиентах БД». Но я думаю, что, вероятно, тип клиента, о котором вы говорите, творит некую нестандартную магию, отличную от SQL. (например, в SQLite запрос sqlite3_master, чтобы выяснить, как преобразовать * в набор имен.)
И дальше от этого, сколько людей пишут код в современных приложениях, которые используют индекс имен столбцов? Большинство людей наверняка используют какой-то картограф и целую кучу кеширования для данных, которым разрешено быть устаревшими. Лично сначала напишите код, а затем беспокойтесь, если позже у вас возникнут проблемы с производительностью.
То, что все сказали выше, плюс:
Если вы стремитесь к удобочитаемому и поддерживаемому коду, сделайте что-нибудь вроде:
ВЫБЕРИТЕ foo, bar FROM виджетов;
мгновенно читается и демонстрирует намерение. Если вы сделаете этот звонок, вы знаете, что получите в ответ. Если у виджетов есть только столбцы foo и bar, то выбор * означает, что вам все равно нужно подумать о том, что вы получаете обратно, подтвердить, что порядок сопоставлен правильно, и т. д. Однако, если у виджетов больше столбцов, но вас интересует только foo и bar, тогда ваш код становится беспорядочным, когда вы запрашиваете подстановочный знак, а затем используете только часть того, что возвращается.
И помните, что если у вас есть внутреннее соединение по определению, вам не нужны все столбцы, поскольку данные в столбцах соединения повторяются.
Это не значит, что перечисление столбцов на сервере SQl сложно или даже отнимает много времени. Вы просто перетаскиваете их из обозревателя объектов (вы можете получить все сразу, перетаскивая их из столбцов слов). Чтобы обеспечить постоянное снижение производительности вашей системы (поскольку это может уменьшить использование индексов и из-за того, что отправка ненужных данных по сети является дорогостоящим) и повысить вероятность возникновения непредвиденных проблем при изменении базы данных (иногда добавляются столбцы, которые вы не хотите, чтобы пользователь, например, видел) просто сэкономить меньше минуты времени на разработку - это недальновидно и непрофессионально.
На данный момент здесь дан ответ на множество веских причин, вот еще одна, о которой не упоминалось.
Явное обозначение столбцов поможет вам в дальнейшем обслуживании. В какой-то момент вы собираетесь вносить изменения или устранять неполадки и обнаруживаете, что спрашиваете, «где, черт возьми, этот столбец используется».
Если у вас есть имена, перечисленные явно, то найти каждую ссылку на этот столбец - через все ваши хранимые процедуры, представления и т. д. - просто. Просто создайте дамп скрипта CREATE для вашей схемы БД и выполните текстовый поиск по нему.
Что касается производительности, я видел комментарии, которые оба равны. но аспект юзабилити есть некоторые плюсы и минусы
Когда вы используете (выберите *) в запросе и если кто-то изменяет таблицу и добавляет новые поля, которые не нужны для предыдущего запроса, это ненужные накладные расходы. А что, если только что добавленное поле - это блоб или поле изображения ??? тогда время ответа на ваш запрос будет очень медленным.
С другой стороны, если вы используете (выберите col1, col2, ..) и если таблица была изменена и добавлены новые поля, и если эти поля необходимы в наборе результатов, вам всегда нужно редактировать свой запрос выбора после изменения таблицы.
Но я предлагаю всегда использовать select col1, col2, ... в ваших запросах и изменять запрос, если таблица будет изменена позже ...
Это старый, но действующий пост. Для справки, у меня очень сложный запрос, состоящий из:
Когда я выполняю запрос с помощью Select *, это занимает в среднем 2869 мс. Когда я выполняю запрос с помощью Select, это занимает в среднем 1513 мс.
Всего возвращено 13 949 строк.
Несомненно, выбор имен столбцов означает более высокую производительность по сравнению с Select *.
Когда нам нужны все столбцы, я думаю, что select * быстрее, чем все столбцы.
На каких доказательствах вы основываете этот вывод?
См. Также: stackoverflow.com/questions/208925/…