Когда вы объявляете ссылочную переменную (т. е. объект), вы действительно создаете указатель на объект. Рассмотрим следующий код, в котором вы объявляете переменную примитивного типа int
:
int x;
x = 10;
В этом примере переменная x является int
, и Java инициализирует ее для 0. Когда вы назначаете его 10 во второй строке, ваше значение 10 записывается в ячейку памяти, на которую указывает x.
Но когда вы пытаетесь объявить ссылочный тип, произойдет что-то другое. Возьмите следующий код:
Integer num;
num = new Integer(10);
Первая строка объявляет переменную с именем num
, но она не содержит примитивного значения. Вместо этого он содержит указатель (потому что тип Integer
является ссылочным типом). Поскольку вы еще не указали, что указать на Java, он устанавливает значение null, что означает «Я ничего не указываю».
Во второй строке ключевое слово new
используется для создания экземпляра (или создания ) объекту типа Integer и переменной указателя num
присваивается этот объект. Теперь вы можете ссылаться на объект, используя оператор разыменования .
(точка).
Exception
, о котором вы просили, возникает, когда вы объявляете переменную, но не создавали объект. Если вы попытаетесь разыменовать num
. Перед созданием объекта вы получите NullPointerException
. В самых тривиальных случаях компилятор поймает проблему и сообщит вам, что «num не может быть инициализирован», но иногда вы пишете код, который непосредственно не создает объект.
Например, вы можете имеют следующий метод:
public void doSomething(SomeObject obj) {
//do something to obj
}
В этом случае вы не создаете объект obj
, скорее предполагая, что он был создан до вызова метода doSomething
. К сожалению, этот метод можно вызвать следующим образом:
doSomething(null);
В этом случае obj
имеет значение null. Если метод предназначен для того, чтобы что-то сделать для переданного объекта, целесообразно бросить NullPointerException
, потому что это ошибка программиста, и программисту понадобится эта информация для целей отладки.
Альтернативно, там могут быть случаи, когда цель метода заключается не только в том, чтобы работать с переданным в объекте, и поэтому нулевой параметр может быть приемлемым. В этом случае вам нужно будет проверить нулевой параметр и вести себя по-другому. Вы также должны объяснить это в документации. Например, doSomething
может быть записано как:
/**
* @param obj An optional foo for ____. May be null, in which case
* the result will be ____.
*/
public void doSomething(SomeObject obj) {
if(obj != null) {
//do something
} else {
//do something else
}
}
Наконец, Как определить исключение & amp; причина использования Трассировки стека
Одна причина, что выбор определенных столбцов лучше, состоит в том, что он повышает вероятность, что SQL Server может получить доступ к данным из индексов вместо того, чтобы запросить данные таблицы.
Вот сообщение, которое я записал об этом: запросы Select настоящей причины являются плохим индексным покрытием
, Это также менее хрупко для изменения, так как любой код, который использует данные, будет получать ту же структуру данных независимо от изменений, которые Вы вносите в схему таблицы в будущем.
С точки зрения эффективности выполнения я не знаю ни о какой значительной разнице. Но для эффективности программистов я написал бы имена полей, потому что
эй, будьте практичны. используйте выбор * при разработке прототипа и выберите определенные столбцы при реализации и развертывании. с точки зрения плана выполнения оба относительно идентичны в современных системах. однако, выбор определенных столбцов ограничивает объем данных, который должен быть получен от диска, сохранил в памяти и отправил по сети.
в конечном счете лучший план состоит в том, чтобы выбрать определенные столбцы.
Также помните об изменениях. Сегодня, Выбор * только выбирает столбцы, в которых Вы нуждаетесь, но завтра он может также выбрать это varbinary (МАКС) столбец, который я только что добавил, не говоря Вам, и Вы теперь также получаете все 3,18 гигабайта Двоичных данных, который вчера не был в таблице.
Если Вам нужен каждый столбец, тогда просто используют ВЫБОР *, но помнят, что порядок мог потенциально измениться поэтому при потреблении результатов, получают доступ к ним по имени а не индексом.
я проигнорировал бы комментарии о том, как * должен пойти, получают список - возможности анализируют и проверяют названные столбцы, равно времени обработки если не больше. Преждевременно не оптимизируйте;-)
Абсолютно определите столбцы, которые Вы хотите ВЫБРАТЬ каждый раз. Нет никакой причины не к, и повышение производительности определенно стоит того.
Они никогда не должны были давать опцию "ВЫБРАТЬ *"
Всегда лучше определить столбцы, в которых Вы нуждаетесь, если Вы думаете об этом одно время, SQL не должен думать "wtf, *", каждый раз Вы запрашиваете. Вдобавок ко всему, кто-то позже может добавить столбцы к таблице, в которой Вы на самом деле не нуждаетесь в своем запросе, и Вы будете более обеспечены в этом случае путем определения всех столбцов.
Определение списка столбцов обычно наилучший вариант, потому что Ваше приложение не будет затронуто, если кто-то добавит/вставит столбец к таблице.
Определение имен столбцов определенно быстрее - для сервера. Но если
тогда Вы более обеспечены липкий с ВЫБОРОМ *. В нашей платформе интенсивное использование ВЫБОРА * позволяет нам представлять новый веб-сайт управляемое поле содержания таблице, давая все это преимуществ CMS (управление версиями, рабочий процесс/одобрения, и т.д.), только касаясь кода в нескольких точках, вместо пары дюжины точек.
я знаю, что гуру DB собираются ненавидеть меня за это - идут вперед, проваливают меня - но в моем мире, время разработчика недостаточно, и циклы ЦП в изобилии, таким образом, я корректирую соответственно, что я сохраняю и что я трачу впустую.
Производительность, мудрая, ИЗБРАННАЯ с определенными столбцами, может быть быстрее (никакая потребность читать во всех данных). Если Ваш запрос действительно использует ВСЕ столбцы, ВЫБОР с помощью явных параметров все еще предпочтен. Любая разность оборотов будет в основном непримечательна и близкая постоянно-разовый. Однажды Ваша схема изменится, и это - хорошая страховка для предотвращения проблем из-за этого.
определенно определяя столбцы, потому что SQL Server не должен будет делать поиска на столбцах для получения по запросу их. Если Вы определяете столбцы, то SQL может пропустить тот шаг.
Проблемой с "выбором *" является возможность обеспечения данных, в которых Вы действительно не нуждаетесь. Во время фактического запроса базы данных выбранные столбцы действительно не добавляют к вычислению. То, что "действительно тяжело", является транспортом данных назад Вашему клиенту, и любой столбец, в котором Вы действительно не нуждаетесь, просто тратит впустую сетевую пропускную способность и добавляет ко времени, Вы ожидаете Вас, запрашивают для возврата.
, Даже если Вы действительно используете все столбцы, принесенные от "выбора *...", это только на данный момент. Если в будущем Вы измените расположение таблицы/представления и добавите больше столбцов, Вы запустите, приносят тем в Ваших выборах, даже если Вам не нужны они.
Другая точка, в которой "выбор *" оператор плох, является выставленным для обозрения созданием. Если Вы создадите представление с помощью "выбор *" и позже добавите столбцы к таблице, определение представления и возвращенные данные не будут соответствовать, и необходимо будет перекомпилировать представления для них для работы снова.
я знаю, что запись "выбора *" заманчива, потому что мне действительно не нравится вручную определять все поля на моих запросах, но когда Ваша система начнет развиваться, Вы будете видеть, что стоит для пребывания в течение этого дополнительного времени / усилие в определении полей вместо того, чтобы провести намного больше времени и ошибок удаления усилия на представлениях или оптимизации приложения.
Выбор одинаково эффективен (с точки зрения скорости), если Вы используете * или столбцы.
различие о памяти, не скорости. То, когда Вы выбираете несколько столбцов SQL Server, должно выделить пространство памяти для обслуживания Вас запрос, включая все данные для всех столбцов, которые Вы запросили, даже если Вы только используете одного из них.
то, Что действительно имеет значение с точки зрения производительности, является планом выполнения, который в свою очередь зависит в большой степени от Вашего оператора Where и количества СОЕДИНЕНИЯ, ВНЕШНЕГО ОБЪЕДИНЕНИЯ, и т.д.
Для Вашего вопроса просто используют ВЫБОР *. При необходимости во всех столбцах нет никакого различия в производительности.
Это не быстрее для использования явных имен полей по сравнению с *, если и только если, необходимо получить данные для всех полей.
Ваше клиентское программное обеспечение не должно зависеть от порядка возвращенных полей, таким образом, это - ерунда также.
И это возможно (хотя вряд ли), что необходимо получить все полевое использование *, потому что Вы еще не знаете, какие поля существуют (думайте структура очень базы динамических данных).
Другой недостаток использования явных имен полей - то, что, если существуют многие из них и они длинны тогда, оно делает чтение кода и/или журнала запросов более трудным.
, Таким образом, правило должно быть: при необходимости во всех полях используйте *, если Вы нуждаетесь в только подмножестве, называете их явно.
Это зависит от версии Вашего сервера БД, но современные версии SQL могут кэшировать план так или иначе. Я сказал бы, идут с тем, что является самым удобным в сопровождении с Вашим кодом доступа к данным.
Одна причина, которую это - лучшая практика для обстоятельного объяснения точно, какие столбцы Вы хотите, из-за возможных будущих изменений в структуре таблицы.
, Если Вы читаете в данных вручную с помощью основанного на индексе подхода для заполнения структуры данных с результатами запроса, затем в будущем, когда Вы добавляете/удаляете столбец, Вы будете страдать от головных болей, пытающихся выяснять то, что пошло не так, как надо.
относительно того, что быстрее, я подчинюсь другим для их экспертных знаний.
Как с большинством проблем, это зависит от того, чего Вы хотите достигнуть. Если Вы хотите создать сетку дб, которая позволит все столбцы в любой таблице, то "Выбор *" является ответом. Однако, если Вам только будут нужны определенные столбцы, и добавляющие или удаляющие столбцы от запроса нечасто делается, затем определите их индивидуально.
Это также зависит от объема данных, который Вы хотите передать с сервера. Если один из столбцов является определенным как записка, графическая, блоб, и т.д. и Вам не нужен тот столбец, Вы лучше не использовали бы "Выбор *", или Вы получите целый набор данных, которые Вы не хотите, и Ваша производительность могла пострадать.
Для прибавления к тому, что все остальные сказали, если все столбцы, которые Вы выбираете, включены в индекс, Ваш набор результатов вытянут от индекса вместо того, чтобы искать дополнительные данные из SQL.
ВЫБЕРИТЕ *, необходимо, если Вы хотите получить метаданные, такие как число столбцов.
В то время как явный список столбцов хорош для производительности, не становитесь сумасшедшими.
Поэтому при использовании всех данных попробуйте ВЫБОР * за простоту (предположите иметь много столбцов и делать, СОЕДИНЕНИЕ... запрашивают, может стать ужасным). Тогда - мера. Сравните с запросом с именами столбцов, перечисленными явно.
не размышляют о производительности, мера это!
Явный список помогает больше всего, когда Вы имеете некоторый столбец, содержащий большие данные (как тело сообщения или статьи), и не нуждаетесь в нем в данном запросе. Тогда, не возвращая его в Вашем сервере БД ответа может сэкономить время, пропускную способность и дисковую пропускную способность. Ваш результат запроса также будет меньшим, который хорош для любого кэша запроса.
Учитывая [1 127] Ваш спецификация, что Вы выбор всех столбцов, существует мало различия в это время . Поймите, однако, что схемы базы данных действительно изменяются. Если Вы используете SELECT *
, Вы собираетесь получить любые новые столбцы, добавленные к таблице, даже при том, что, по всей вероятности, Ваш код не готов использовать или представить те новые данные. Это означает представление системы неожиданной производительности и изменениям функциональности.
можно быть готовы отклонить это как незначительную стоимость, но понять, что столбцы, в которых Вы не нуждаетесь все еще, должны быть:
, Объект № 1 имеет много скрытых затрат включая устранение некоторого потенциального закрывающего индекса, вызывая загрузки страницы данных (и перегрузка кэша сервера), подвергаясь строке / страница / блокировки таблицы, которых можно было бы иначе избежать.
Баланс это против потенциальных сбережений определения столбцов по сравнению с *
и единственных потенциальных сбережений:
Для объекта 1, действительность - то, что Вы собираетесь добавить / код изменения для использования любого нового столбца, который Вы могли бы добавить так или иначе, таким образом, это - промывка.
Для объекта 2, различие достаточно редко для продвижения Вас в различный размер пакета или количество сетевых пакетов. Если Вы переходите к сути дела, где время передачи SQL-оператора является преобладающей проблемой, вероятно, необходимо уменьшить уровень операторов сначала.
Для объекта 3, нет НИКАКИХ сбережений, поскольку расширение *
должно произойти так или иначе, что означает консультироваться со схемой таблицы (таблиц) так или иначе. Реалистично, список столбцов понесет те же расходы, потому что они должны быть проверены против схемы. Другими словами, это - полная промывка.
Для объекта 4 при определении определенных столбцов кэш плана запросов мог стать больше, но [только 1 133], если Вы имеете дело с различными наборами столбцов (который не является тем, что Вы определили). В этом случае Вы действительно хотите различные записи кэша, потому что Вы хотите различные планы по мере необходимости.
Так, это все снижается из-за способа, которым Вы определили вопрос к упругости проблемы перед лицом возможных модификаций схемы. При записи этой схемы в ROM (это происходит), то *
совершенно приемлемо.
Однако мое общее руководство - то, что необходимо только выбрать столбцы, в которых Вы нуждаетесь, что означает, что иногда будет похоже, что Вы просите всех их, но DBAs и эволюция схемы означают, что некоторые новые столбцы могли бы появиться, который мог значительно влиять на запрос.
Мой совет состоит в том, что Вы должны ВСЕГДА ВЫБИРАТЬ определенные столбцы . Помните, что Вы становитесь хорошими в том, что Вы действительно много раз, так просто привыкаете делать его правильно.
, Если Вы задаетесь вопросом, почему схема могла бы измениться без изменения кода, думайте с точки зрения входа аудита, эффективных / дат истечения срока и других подобных вещей, которые добавляются DBAs для систематически для проблем соответствия. Другой источник закулисных изменений является денормализациями для производительности в другом месте в системе или пользовательских полях.
И помните, если у вас есть внутреннее объединение, по определению вам не нужны все столбцы, так как данные в столбцах объединения повторяются.
Не то чтобы перечисление столбцов в SQl server было трудным или даже отнимало много времени. Вы просто перетаскиваете их из браузера объектов (можно получить все за один раз, перетащив из слова columns). Наносить постоянный удар по производительности вашей системы (потому что это может уменьшить использование индексов и потому что отправка ненужных данных по сети стоит дорого) и увеличивать вероятность возникновения неожиданных проблем при изменении базы данных (иногда добавляются колонки, которые вы не хотите, чтобы пользователь видел, например) только для того, чтобы сэкономить менее минуты времени разработки, - это недальновидно и непрофессионально.
SELECT * - плохая практика, даже если запрос не передается по сети.
Конечно, все это не имеет большого значения для небольшой и простой системы.
Именование каждого столбца, который вы ожидаете получить в вашем приложении, также гарантирует, что ваше приложение не сломается, если кто-то изменит таблицу, пока ваши столбцы все еще присутствуют (в любом порядке).
Вы действительно должны выбирать только те поля, которые вам нужны, и только необходимое количество, то есть
SELECT Field1, Field2 FROM SomeTable WHERE --(constraints)
Вне базы данных динамические запросы подвержены риску атак путем внедрения и искажения данных. Обычно это обходится с помощью хранимых процедур или параметризованных запросов. Кроме того (хотя на самом деле это не такая уж большая проблема) сервер должен генерировать план выполнения каждый раз, когда выполняется динамический запрос.
Пока здесь было дано множество веских ответов, вот еще одна, о которой не упоминалось.
Явное указание столбцов поможет вам в дальнейшем обслуживании. В какой-то момент вы собираетесь вносить изменения или устранять неполадки и обнаруживаете, что спрашиваете, «где, черт возьми, этот столбец используется».
Если у вас есть имена, перечисленные явно, то найти каждую ссылку на этот столбец - во всех ваших хранимых процедурах, представлениях и т. Д. - просто. Просто создайте дамп скрипта CREATE для вашей схемы БД и выполните текстовый поиск по нему.
Вы должны выбирать только те столбцы, которые вам нужны. Даже если вам нужны все столбцы, все равно лучше указать имена столбцов, чтобы серверу sql не приходилось запрашивать столбцы в системной таблице.
Кроме того, ваше приложение может сломаться, если кто-то добавит столбцы в таблицу. Ваша программа также получит столбцы, которых она не ожидала, и может не знать, как их обрабатывать.
Кроме того, если в таблице есть двоичный столбец, запрос будет намного медленнее и потребует больше сетевых ресурсов.
Результат слишком велик. Генерация и отправка результата от механизма SQL клиенту выполняется медленно.
Клиентская сторона, являясь общей средой программирования, не предназначена и не должна быть предназначена для фильтрации и обработки результатов (например, предложение WHERE, предложение ORDER), поскольку количество строк может быть огромным (например, десятки миллионов ряды).
Есть четыре большие причины, по которым select *
- это плохо:
Самая важная практическая причина заключается в том, что он заставляет пользователя волшебным образом узнать порядок, в котором столбцы будут возвращены. Лучше быть явным, что также защитит вас от изменения таблицы, которая прекрасно переходит в ...
Если имя столбца, которое вы используете, изменяется, лучше поймать его на раннем этапе (в момент вызова SQL) а не когда вы пытаетесь использовать столбец, который больше не существует (или имя которого было изменено и т. д.)
Перечисление имен столбцов делает ваш код более самодокументированным и, следовательно, более читабельным.
Если вы выполняете передачу по сети (или даже если это не так), столбцы, которые вам не нужны, просто бесполезны.
То, что сказали все выше, плюс:
Если вы стремитесь к читаемому сопровождаемому коду, делайте что-то вроде:
SELECT foo, bar FROM widgets;
это мгновенно читаемо и показывает намерение. Если вы делаете такой вызов, вы знаете, что получите в ответ. Если виджеты имеют только столбцы foo и bar, то выбор * означает, что вам все равно придется думать о том, что вы получите в ответ, подтверждать правильность порядка следования и т. д. Однако, если у виджетов больше столбцов, но вас интересуют только foo и bar, то ваш код становится запутанным, когда вы запрашиваете подстановочный знак, а затем используете только часть того, что возвращается.