Может выбрать * использование когда-нибудь быть выровненным по ширине?

Я всегда проповедовал своим разработчикам это SELECT * является злым и должен избегаться как чумы.

Есть ли какие-либо случаи, где это может быть выровнено по ширине?

Я не говорю о COUNT(*) - который может выяснить большинство оптимизаторов.

Править

Я говорю о производственном коде.

И один яркий пример, который я видел этой плохой практики, был приложением asp прежней версии, которое использовало select * в хранимой процедуре, и используемый ADO циклично выполняться через возвращенные записи, но получило столбцы индексом. Можно вообразить то, что произошло, когда новое поле было добавлено где-нибудь кроме конца cписка полей.

62
задан 5 September 2010 в 10:50

20 ответов

Я - довольно счастливое использование * в контрольных триггерах.

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

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

WITH t
     AS (SELECT *,
                ROW_NUMBER() OVER (ORDER BY a) AS RN
         FROM   foo)
SELECT a,
       b,
       c,
       RN
FROM   t; 

я главным образом знаком с SQL Server, и там по крайней мере, оптимизатор не имеет никакой проблемы при распознавании, что только столбцы a,b,c будут требоваться, и использование * во внутреннем выражении таблицы не вызывает ненужного служебного получения и отбрасывания ненужных столбцов.

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

45
ответ дан 31 October 2019 в 13:18

Если Вы хотите найти все столбцы и хотеть порядок, можно сделать следующее (по крайней мере, при использовании MySQL):

SHOW COLUMNS FROM mytable FROM mydb; (1)

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

"select " + fieldNames[0] + ", fieldNames[1]" + ", fieldNames[2] from mytable". (2)

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

0
ответ дан 31 October 2019 в 13:18

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

select * 
into staging.aTable 
from remotedb.dbo.aTable

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

0
ответ дан 31 October 2019 в 13:18

Select * в производственном коде допустимо любое время когда:

  • это не узкое место производительности
  • , время разработки очень важно

, Почему я хотел бы издержки возвращения и необходимости волноваться об изменении соответствующих хранимых процедур, каждый раз, когда я добавляю поле к таблице?

, Почему я даже хотел бы должным быть думать о том, выбрал ли я правые стороны поля, когда подавляющее большинство времени я хочу большинство из них так или иначе и подавляющее большинство нескольких раз, я не делаю, что-то еще - узкое место?

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

<час>

Редактирование.. после обсуждения я предполагаю, что добавил бы к этому:

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

0
ответ дан 31 October 2019 в 13:18

Зависит от контекста производственного программного обеспечения.

, Если Вы пишете простой уровень доступа к данным для инструмента управления таблицы, где пользователь будет выбирать таблицы и просматривать результаты в сетке, затем это казалось бы *, ВЫБОР ** прекрасен.

, Другими словами, если Вы принимаете решение обработать "выбор полей" через некоторые другие средства (как в автоматических или указанных пользователями фильтрах после получения набора результатов) затем, это кажется очень хорошо.

, Если, с другой стороны, мы говорим о своего рода программном обеспечении предприятия с бизнес-правилами, определенной схемой, и т.д.... затем, я соглашаюсь, что *ВЫБОР ** является плохой идеей.

РЕДАКТИРОВАНИЕ: О, и когда исходная таблица является хранимой процедурой для триггера или представления, "*SELECT **" должен быть прекрасным, потому что Вы управляете набором результатов через другие средства (определение представления или набор результатов сохраненного proc).

0
ответ дан 31 October 2019 в 13:18
  1. я должен был несколько раз отображать данные из таблицы, имена столбцов которой были неизвестны. Таким образом, я сделал SELECT * и получил имена столбцов во время выполнения.

  2. мне вручили приложение прежней версии, где таблица имела 200 столбцов, и представление имело 300. Рискозависимость от SELECT * была бы не хуже, чем из списка всех 300 столбцов явно.

1
ответ дан 31 October 2019 в 13:18

Да, но только в ситуациях, где намерение состоит в том, чтобы на самом деле получить все столбцы от таблицы, не потому что Вы хотите все столбцы, которые в настоящее время имеет таблица.

, Например, в одной системе, что я продолжил работать, у нас был UDFs (Определяемые пользователем Поля), где пользователь мог выбрать поля, они хотели на отчете, порядке, а также фильтрации. При создании набора результатов это имело больше смысла только к "выбору *" из временных таблиц, которые я создавал вместо того, чтобы иметь необходимость отслеживать, которых столбцы были активны.

1
ответ дан 31 October 2019 в 13:18

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

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

На практике, я придерживаюсь SELECT * для 3 случаев (некоторые упомянутые в других ответах:

  • Как специальный запрос, вводимый в GUI SQL или командную строку.
  • Как содержание EXISTS предикат.
  • В приложении, которое имело дело с универсальными таблицами, не будучи должен знать то, что они имеют в виду (например, самосвал или отличаются).
1
ответ дан 31 October 2019 в 13:18

Как еще делают разработчики phpmyadmin удостоверяются, что они отображают все поля Ваших Таблиц базы данных?

2
ответ дан 31 October 2019 в 13:18

Я привык выбор * для таблиц запроса, оптимизированных для чтения (денормализованные, плоские данные). Очень выгодный начиная с цели таблиц должны были просто поддерживать различные представления в приложении.

2
ответ дан 31 October 2019 в 13:18

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

было одно недавнее место, где моя команда использовала SELECT *, и я думаю, что она была в порядке... у нас есть база данных, которая существует как фасад против другой базы данных (назовите ее DB_Data), таким образом, она, прежде всего, составлена из представлений против таблиц в другой базе данных. Когда мы генерируем представления, мы на самом деле генерируем списки столбцов, но существует один набор представлений в базе данных DB_Data, которые автоматически сгенерированы, поскольку строки добавляются к универсальной справочной таблице (этот дизайн существовал, прежде чем я добрался здесь). Мы записали триггер DDL так, чтобы, когда представление создается в DB_Data этим процессом затем, другое представление было автоматически создано в фасаде. Так как представление всегда сгенерировано для точного соответствия представлению в DB_Data и всегда обновляется и сохраняется в синхронизации, мы просто использовали SELECT * для простоты.

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

2
ответ дан 31 October 2019 в 13:18

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

2
ответ дан 31 October 2019 в 13:18

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

2
ответ дан 31 October 2019 в 13:18

И помните, используете ли Вы выбор *, и у Вас есть соединение, которое по крайней мере одно поле будет отправлено дважды (объединяющее поле). Это тратит впустую ресурсы базы данных и сетевые ресурсы ни по какой причине.

4
ответ дан 31 October 2019 в 13:18

Вы получили много ответов на свой вопрос, но Вы, кажется, отклоняете все, что не бессмысленно повторяет назад, что Вы хотите услышать. Однако, здесь это - для третьего (до сих пор) время: иногда там никакое узкое место. Иногда производительность является путем лучше, чем прекрасный. Иногда таблицы в движении, и исправление каждого Запроса Select является просто еще одним битом возможного несоответствия для управления. Иногда необходимо поставить в невозможном расписании, и это - последняя вещь, о которой необходимо думать.

, Если Вы живете во время маркера, уверенное, тип во всех именах столбцов. Но почему остановка там? Перепишите свое приложение в бессхемной DBMS. Черт, запишите Ваш собственный DBMS в блоке. Это действительно показало бы им.

6
ответ дан 31 October 2019 в 13:18

В производственном коде я был бы склонен согласовывать 100% с Вами.

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

7
ответ дан 31 October 2019 в 13:18

Я думаю с помощью select * в exists, пункт является соответствующим:

select some_field from some_table 
where exists 
 (select * from related_table [join condition...])

Некоторым людям нравится использовать select 1 в этом случае, но это не изящно, и это не покупает никакой повышения производительности (ранние забастовки оптимизации снова).

16
ответ дан 31 October 2019 в 13:18

Ни один, о чем я могу думать, если Вы говорите о живом коде.

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

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

25
ответ дан 31 October 2019 в 13:18

Я буду использовать его в производстве при работе с CTEs. Но, в этом случае это не действительно select *, потому что я уже указал столбцы в CTE. Я просто не хочу повторно указывать в заключительном выборе.

with t as (
    select a, b, c from foo
)

select t.* from t;
28
ответ дан 31 October 2019 в 13:18

Существует много сценариев, где ВЫБОР * является оптимальным решением. При выполнении специальных запросов в Studio управления только для получения смысла данных Вы работаете с. При запросах таблиц, где Вы еще не знаете имен столбцов, потому что это - первый раз, Вы работали с новой схемой. Создание доступных quick'n'dirty инструментов, чтобы сделать одноразовую миграцию или экспорт данных.

я согласился бы, что в "надлежащей" разработке, необходимо избежать его - но существует много сценариев, где "надлежащая" разработка является не обязательно оптимальным решением бизнес-проблемы. Правила и лучшие практики являются большими, пока Вы знаете, когда повредить их. :)

34
ответ дан 31 October 2019 в 13:18

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

Похожие вопросы: