Может ли выбор * использование когда-либо быть оправданным? - PullRequest
62 голосов
/ 03 сентября 2010

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

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

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

1009 ** * Редактировать 1010 ** * 1011

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

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

Ответы [ 20 ]

2 голосов
/ 03 сентября 2010

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

2 голосов
/ 03 сентября 2010

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

2 голосов
/ 04 сентября 2010

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

1 голос
/ 03 сентября 2010
  1. Мне несколько раз требовалось отобразить данные из таблицы, имена столбцов которой были неизвестны. Поэтому я сделал SELECT * и получил имена столбцов во время выполнения.

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

1 голос
/ 03 сентября 2010

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

Например, в одной системе, над которой я работал, у нас были UDF (пользовательские поля), где пользователь мог выбирать нужные поля в отчете, порядок и фильтрацию. При создании результирующего набора имело больше смысла просто «выбирать *» из создаваемых мной временных таблиц, вместо того, чтобы отслеживать, какие столбцы были активными.

1 голос
/ 03 сентября 2010

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

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

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

  • В качестве специального запроса, вводится в графическом интерфейсе или командной строке SQL.
  • В качестве содержимого предиката EXISTS.
  • В приложении, которое обрабатывает общие таблицы без необходимостичтобы знать, что они имеют в виду (например, самосвал или отличаются).
0 голосов
/ 26 марта 2015

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

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

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

0 голосов
/ 05 сентября 2010

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

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

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

Если, с другой стороны,мы говорим о каком-то корпоративном программном обеспечении с бизнес-правилами, определенной схемой и т. д. ... тогда я согласен, что * SELECT ** - плохая идея.

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

0 голосов
/ 03 сентября 2010

Select * в рабочем коде оправдано в любое время, когда:

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

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

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

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


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

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

0 голосов
/ 04 сентября 2010

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

SHOW COLUMNS FROM mytable FROM mydb; (1)

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...