Я слышал, что SELECT *
это обычно плохая практика для написания команд SQL, потому что это более эффективно для SELECT
столбцов, которые вам особенно нужны.
Если мне нужно, чтобы SELECT
каждый столбец в таблице, я должен использовать
SELECT * FROM TABLE
или
SELECT column1, colum2, column3, etc. FROM TABLE
Эффективность действительно имеет значение в этом случае? Я думаю, что SELECT *
было бы более оптимальным внутренне, если вам действительно нужны все данные, но я говорю это без реального понимания базы данных.
Мне любопытно узнать, какова лучшая практика в этом случае.
ОБНОВЛЕНИЕ: Я, вероятно, должен указать, что единственная ситуация, в которой я действительно хотел бы сделать, - SELECT *
это когда я выбираю данные из одной таблицы, где я знаю, что все столбцы всегда нужно будет извлекать, даже когда добавляются новые столбцы.
Однако, учитывая ответы, которые я видел, это все еще кажется плохой идеей и SELECT *
никогда не должно использоваться по гораздо более техническим причинам, чем я когда-либо думал.
Ответы:
Одна из причин, по которой лучше выбирать конкретные столбцы, заключается в том, что это повышает вероятность того, что SQL Server сможет получить доступ к данным из индексов, а не запрашивать данные таблицы.
Вот сообщение, которое я написал об этом: реальная причина, по которой запросы на выборку - плохое покрытие индекса
Изменения также менее хрупкие, поскольку любой код, потребляющий данные, будет получать ту же структуру данных независимо от изменений, которые вы внесете в схему таблицы в будущем.
источник
vs
all_column_names), в то время как у нас есть тысячи строк, и мы выполняем SELECT с индексом (в предложении WHERE) ??Учитывая ваши спецификации , что вы являетесь выбором всех столбцов, есть небольшая разница в это время . Поймите, однако, что схемы базы данных меняются. Если вы используете его,
SELECT *
вы добавите в таблицу новые столбцы, хотя, по всей вероятности, ваш код не готов к использованию или представлению этих новых данных. Это означает, что вы подвергаете свою систему неожиданным изменениям производительности и функциональности.Возможно, вы захотите отклонить это как незначительные расходы, но поймите, что столбцы, которые вам не нужны, по-прежнему должны быть:
Элемент № 1 имеет много скрытых затрат, в том числе устранение некоторого потенциального индекса покрытия, вызывая загрузки страниц данных (и перебор кэша сервера), влекущие за собой блокировки строк / страниц / таблиц, которых в противном случае можно было бы избежать.
Соотнесите это с потенциальной экономией при указании столбцов и an,
*
и единственная потенциальная экономия:Для пункта 1 реальность такова, что вы собираетесь добавить / изменить код, чтобы использовать любой новый столбец, который вы можете добавить в любом случае, так что это мойка.
Для пункта 2 различие достаточно редко, чтобы подтолкнуть вас к другому размеру пакета или количеству сетевых пакетов. Если вы дойдете до того момента, когда преобладающим вопросом будет время передачи операторов SQL, вам, вероятно, сначала нужно уменьшить скорость операторов.
Для пункта 3 экономия НЕТ, так как расширение
*
должно произойти в любом случае, что означает, в любом случае, обращение к схеме таблиц. Реально, перечисление столбцов будет стоить одинаково, потому что они должны быть проверены по схеме. Другими словами, это полная стирка.Для элемента 4, когда вы указываете конкретные столбцы, кэш плана запросов может увеличиться, но только если вы имеете дело с различными наборами столбцов (что не соответствует указанному вами). В этом случае вам нужны разные записи в кэше, потому что вам нужны разные планы по мере необходимости.
Таким образом, все это сводится к тому, как вы задали вопрос, к устойчивости проблемы перед лицом возможных изменений схемы. Если вы записываете эту схему в ПЗУ (это происходит), то
*
вполне допустимо.Однако мое общее правило заключается в том, что вы должны выбирать только те столбцы, которые вам нужны, что означает, что иногда все выглядит так, будто вы запрашиваете все из них, но администраторы баз данных и эволюция схемы означают, что могут появиться некоторые новые столбцы, которые могут сильно повлиять на запрос. ,
Мой совет, что вы должны всегда выбирать конкретные столбцы . Помните, что вы хорошо разбираетесь в том, что вы делаете снова и снова, поэтому просто привыкните делать это правильно.
Если вам интересно, почему схема может измениться без изменения кода, подумайте о журнале аудита, датах вступления в силу / истечении срока действия и других подобных вещах, которые добавляются администраторами баз данных для системного разрешения проблем соответствия. Другим источником скрытых изменений является денормализация производительности в других местах системы или пользовательских полей.
источник
Вы должны выбрать только те столбцы, которые вам нужны. Даже если вам нужны все столбцы, все равно лучше перечислить имена столбцов, чтобы серверу sql не приходилось запрашивать системные столбцы для столбцов.
Кроме того, ваше приложение может сломаться, если кто-то добавит столбцы в таблицу. Ваша программа получит столбцы, которых она не ожидала, и может не знать, как их обрабатывать.
Помимо этого, если в таблице есть двоичный столбец, запрос будет выполняться намного медленнее и использовать больше сетевых ресурсов.
источник
Есть четыре причины, по которым
select *
это плохо:Наиболее значимая практическая причина заключается в том, что он заставляет пользователя волшебным образом знать порядок, в котором будут возвращаться столбцы. Лучше быть явным, что также защищает вас от смены таблицы, которая хорошо переходит в ...
Если имя столбца, которое вы используете, изменяется, лучше перехватить его раньше (в момент вызова SQL), а не когда вы пытаетесь использовать столбец, который больше не существует (или его имя изменилось, и т. Д.). )
Перечисление имен столбцов делает ваш код намного более самодокументированным и, вероятно, более читабельным.
Если вы осуществляете передачу по сети (или даже если нет), столбцы, которые вам не нужны, просто напрасны.
источник
*
набор имен.)Указание списка столбцов обычно является наилучшим вариантом, потому что ваше приложение не будет затронуто, если кто-то добавит / вставит столбец в таблицу.
источник
Указывать имена столбцов определенно быстрее - для сервера. Но если
тогда вам лучше придерживаться SELECT *. В нашей среде интенсивное использование SELECT * позволяет нам вводить новое поле управляемого содержимого веб-сайта в таблицу, предоставляя ему все преимущества CMS (управление версиями, рабочий процесс / утверждения и т. Д.), При этом только касаясь кода на пара баллов, вместо пары десятков баллов.
Я знаю, что гуру БД возненавидят меня за это - продолжайте, проголосуйте за меня - но в моем мире времени разработчиков мало, а циклов ЦП много, поэтому я соответствующим образом корректирую то, что я сохраняю и что я трачу.
источник
SELECT * - плохая практика, даже если запрос не передается по сети.
Конечно, все это не имеет большого значения для маленькой и простой системы.
источник
С точки зрения производительности, SELECT с определенными столбцами может быть быстрее (не нужно читать все данные). Если ваш запрос действительно использует ВСЕ столбцы, SELECT с явными параметрами по-прежнему предпочтительнее. Любая разница в скорости будет в основном незаметной и почти постоянной. Однажды ваша схема изменится, и это хорошая страховка, чтобы избежать проблем из-за этого.
источник
Пока на это есть много веских причин, вот еще одна, которая не была упомянута.
Явное присвоение имен столбцам поможет вам в обслуживании в будущем. В какой-то момент вы будете вносить изменения или устранять неполадки, и вы задаетесь вопросом: «Где, черт возьми, этот столбец используется»?
Если у вас есть имена, перечисленные в явном виде, то найти каждую ссылку на этот столбец - через все ваши хранимые процедуры, представления и т. Д. - просто. Просто дамп сценария CREATE для вашей схемы БД и текстовый поиск по нему.
источник
определенно определяя столбцы, потому что SQL Server не нужно будет искать столбцы для их извлечения. Если вы определяете столбцы, то SQL может пропустить этот шаг.
источник
Всегда лучше указывать нужные столбцы, если вы думаете об этом один раз, SQL не должен думать «wtf is *» каждый раз, когда вы запрашиваете. Кроме того, кто-то позже может добавить столбцы в таблицу, которые вам на самом деле не нужны в вашем запросе, и вам будет лучше в этом случае, указав все ваши столбцы.
источник
Проблема с «select *» заключается в возможности получения данных, которые вам не нужны. Во время фактического запроса к базе данных выбранные столбцы не добавляются к вычислениям. Что действительно «тяжело», так это передача данных обратно вашему клиенту, и любой столбец, который вам на самом деле не нужен, просто тратит пропускную способность сети и увеличивает время ожидания запроса на возврат.
Даже если вы используете все столбцы, извлеченные из «select * ...», это только сейчас. Если в будущем вы измените макет таблицы / представления и добавите больше столбцов, вы начнете вносить их в выбранные элементы, даже если они вам не нужны.
Еще один момент, в котором утверждение «select *» является плохим, - это создание представления. Если вы создаете представление с помощью «select *», а затем добавляете столбцы в таблицу, определение представления и возвращаемые данные не будут совпадать, и вам нужно будет перекомпилировать ваши представления, чтобы они снова заработали.
Я знаю, что написание "select *" заманчиво, потому что я действительно не люблю вручную указывать все поля в моих запросах, но когда ваша система начнет развиваться, вы увидите, что стоит потратить это дополнительное время / усилия по определению полей вместо того, чтобы тратить гораздо больше времени и усилий на устранение ошибок в ваших представлениях или оптимизацию вашего приложения.
источник
Хотя явное перечисление столбцов хорошо для производительности, не сходите с ума.
Поэтому, если вы используете все данные, попробуйте SELECT * для простоты (представьте, что у вас много столбцов и выполнение запроса JOIN ... может оказаться ужасным). Тогда - мера. Сравните с запросом с явно указанными именами столбцов.
Не рассуждайте о производительности, измерьте ее!
Явный листинг помогает больше всего, когда у вас есть какой-то столбец, содержащий большие данные (например, текст сообщения или статьи), и он вам не нужен в данном запросе. Тогда, не возвращая его в ответе, сервер БД может сэкономить время, пропускную способность и пропускную способность диска. Ваш результат запроса также будет меньше, что хорошо для любого кеша запросов.
источник
Вы действительно должны выбрать только те поля, которые вам нужны, и только необходимое количество, т.е.
Вне базы данных динамические запросы подвергаются риску инъекционных атак и искаженных данных. Обычно вы обходите это с помощью хранимых процедур или параметризованных запросов. Также (хотя это и не так уж и большая проблема) сервер должен генерировать план выполнения каждый раз, когда выполняется динамический запрос.
источник
Выбор одинаково эффективен (с точки зрения скорости), если вы используете * или столбцы.
Разница в памяти, а не в скорости. При выборе нескольких столбцов SQL Server должен выделять пространство памяти для обслуживания запроса, включая все данные для всех запрошенных столбцов, даже если вы используете только один из них.
Что важно с точки зрения производительности, так это план исключений, который, в свою очередь, сильно зависит от вашего предложения WHERE и количества JOIN, OUTER JOIN и т. Д.
Для вашего вопроса просто используйте SELECT *. Если вам нужны все столбцы, разница в производительности отсутствует.
источник
НЕТ быстрее использовать явные имена полей по сравнению с *, если и только если вам нужно получить данные для всех полей.
Ваше клиентское программное обеспечение не должно зависеть от порядка возвращаемых полей, так что это тоже чепуха.
И возможно (хотя и маловероятно), что вам нужно получить все поля, используя *, потому что вы еще не знаете, какие поля существуют (представьте себе очень динамичную структуру базы данных).
Другим недостатком использования явных имен полей является то, что если их много и они длинные, это затрудняет чтение кода и / или журнала запросов.
Таким образом, правило должно быть таким: если вам нужны все поля, используйте *, если вам нужно только подмножество, назовите их явно.
источник
Результат слишком велик. Медленно генерировать и отправлять результат из механизма SQL клиенту.
Клиентская сторона, являясь универсальной средой программирования, не предназначена и не должна быть предназначена для фильтрации и обработки результатов (например, предложение WHERE, предложение ORDER), поскольку число строк может быть огромным (например, десятки миллионов строк).
источник
Обозначение каждого столбца, который вы ожидаете получить в своем приложении, также гарантирует, что ваше приложение не сломается, если кто-то изменит таблицу, если ваши столбцы все еще присутствуют (в любом порядке).
источник
Это зависит от версии вашего сервера БД, но современные версии SQL могут кэшировать план в любом случае. Я бы сказал, что с вашим кодом доступа к данным лучше всего поддерживать.
источник
Одна из причин, по которой лучше точно указывать, какие столбцы вы хотите - это возможные будущие изменения в структуре таблицы.
Если вы читаете данные вручную, используя индексный подход, чтобы заполнить структуру данных результатами вашего запроса, то в будущем, когда вы добавите / удалите столбец, у вас будут головные боли, пытаясь выяснить, что пошло не так.
Что касается того, что быстрее, я буду полагаться на других за их опыт.
источник
Как и в случае большинства проблем, это зависит от того, чего вы хотите достичь. Если вы хотите создать сетку БД, которая будет разрешать все столбцы в любой таблице, тогда ответом будет «Выбрать *». Однако если вам нужны только определенные столбцы, а добавление или удаление столбцов из запроса выполняется нечасто, укажите их по отдельности.
Это также зависит от объема данных, которые вы хотите передать с сервера. Если один из столбцов определен как памятка, графика, блоб и т. Д. И вам не нужен этот столбец, лучше не использовать «Выбрать *», либо вы получите целую кучу данных, которые вам не нужны хочу, и ваша производительность может пострадать.
источник
В дополнение к тому, что сказали все остальные, если все выбранные вами столбцы включены в индекс, ваш набор результатов будет извлечен из индекса вместо поиска дополнительных данных из SQL.
источник
SELECT * необходим, если требуется получить метаданные, например количество столбцов.
источник
Что все выше сказанное, плюс:
Если вы стремитесь к читаемому сопровождаемому коду, сделайте что-то вроде:
SELECT foo, панель ОТ виджетов;
мгновенно читается и показывает намерение. Если вы сделаете этот звонок, вы знаете, что вы получаете обратно. Если в виджетах есть только столбцы foo и bar, то выбор * означает, что вам все равно нужно подумать о том, что вы получаете, подтвердить правильность отображения порядка и т. Д. Однако, если виджеты имеют больше столбцов, но вас интересует только foo и бар, тогда ваш код становится грязным, когда вы запрашиваете шаблон, а затем используете только часть из того, что было возвращено.
источник
И помните, что если у вас есть внутреннее объединение по определению, вам не нужны все столбцы, поскольку данные в столбцах объединения повторяются.
Это не значит, что перечисление столбцов на сервере SQl сложно или даже отнимает много времени. Вы просто перетаскиваете их из браузера объектов (вы можете получить все сразу, перетаскивая из столбцов слов). Постоянное снижение производительности вашей системы (поскольку это может сократить использование индексов и, как следствие, пересылка ненужных данных по сети, является дорогостоящим) и повысить вероятность возникновения непредвиденных проблем при изменении базы данных (иногда добавляются столбцы, которые вы не хотите, чтобы пользователь видел, например) просто сэкономить меньше минуты времени на разработку - недальновидно и непрофессионально.
источник
По производительности я видел комментарии, которые оба равны. но аспект юзабилити есть некоторые + и
Когда вы используете (select *) в запросе и если кто-то изменяет таблицу и добавляет новые поля, которые не нужны для предыдущего запроса, это приводит к ненужным накладным расходам. А что, если недавно добавленное поле является блобом или полем изображения ??? тогда ваше время ответа на запрос будет очень медленным.
С другой стороны, если вы используете (выберите col1, col2, ..) и если таблица изменена и добавлены новые поля, и если эти поля необходимы в наборе результатов, вам всегда нужно редактировать запрос на выбор после изменения таблицы.
Но я предлагаю всегда использовать select col1, col2, ... в ваших запросах и изменять запрос, если таблица будет изменена позже ...
источник
Абсолютно определите столбцы, которые вы хотите ВЫБРАТЬ каждый раз. Нет причин не делать этого, и улучшение производительности того стоит.
Они никогда не должны были давать возможность «SELECT *»
источник
Если вам нужен каждый столбец, просто используйте SELECT *, но помните, что порядок может потенциально измениться, поэтому, когда вы используете результаты, обращайтесь к ним по имени, а не по индексу.
Я бы проигнорировал комментарии о том, как * нужно получить список - шансы разбора и проверки именованных столбцов равны времени обработки, если не больше. Не преждевременно оптимизировать ;-)
источник
С точки зрения эффективности исполнения я не знаю какой-либо существенной разницы. Но для эффективности программистов я бы написал названия полей, потому что
источник
эй, будь практичным. используйте select * при создании прототипа и выберите конкретные столбцы при внедрении и развертывании. с точки зрения плана выполнения, оба относительно идентичны в современных системах. однако выбор определенных столбцов ограничивает объем данных, которые должны быть извлечены с диска, сохранены в памяти и отправлены по сети.
в конечном счете, лучший план - выбрать конкретные столбцы.
источник