Использование «select *» для курсора в PL / SQL считается плохим программированием? - PullRequest
2 голосов
/ 10 февраля 2012

Часто я использую курсоры следующим образом:

for rec in (select * from MY_TABLE where MY_COND = ITION) loop
    if rec.FIELD1 = 'something' then
        do_something();
    end if;

    if rec.FIELD2 <> 'somethingelse' then
        blabla();
    end if;
end loop;

Мой руководитель группы сказал мне не использовать select *, потому что это плохое программирование, но я не понимаю почему (в этом контексте).

Ответы [ 5 ]

9 голосов
/ 10 февраля 2012

Использование select * в вашем коде - это то, что я бы назвал ленивым программированием с несколькими неприятными побочными эффектами. Степень, с которой вы испытываете эти побочные эффекты, будет отличаться, но она никогда не бывает положительной.

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

  1. Вы отправляете больше данных из механизма SQL в ваш код, чем необходимо, что отрицательно влияет на производительность.

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

  3. Используя select *, вы никогда не будете использовать только индекс для получения требуемой информации, вам всегда придется также посещать таблицу (при условии, что не существует индекса, который содержит все столбцы таблицы). Опять же, с отрицательным влиянием на производительность.

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

  5. Вы не будете использовать функции SQL для выполнения вычислений, но всегда будете полагаться на вычисления PL / SQL или Java. Возможно, вам не хватает некоторых значительных улучшений SQL, таких как аналитические функции, предложение модели, рекурсивный факторинг подзапросов и т. П.

  6. Начиная с Oracle11, зависимости отслеживаются на уровне столбцов. Это означает, что при использовании select * ваш код помечается в словаре данных как «зависимый от всех столбцов» этой таблицы. Ваша процедура будет признана недействительной, если что-то случится с одним из этих столбцов. Поэтому использование select * означает, что ваш код будет признан недействительным чаще, чем необходимо.

Опять же, не стесняйтесь добавлять свои собственные очки.

5 голосов
/ 10 февраля 2012

Выбор большего количества полей, чем необходимо, имеет несколько недостатков:

  • Менее ясно - select c1, c2 сразу показывает, какие столбцы извлекаются, без необходимости разбираться в коде.
  • ... также менее понятен для людей, ответственных за администрирование / настройку БД - они могут только видеть запросы в журналах, лучше не заставлять их анализировать код, сгенерировавший запросы.
  • предотвращает некоторыеОптимизация запросов - select c2 from t where c2<=5, если у вас есть индекс на c2, есть шанс извлечь значение c2 из самого индекса, не выбирая записи.select * ... делает это невозможным.
1 голос
/ 10 февраля 2012

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

EDIT Эффекты, которые не видны в основном, перечислены Codo и Rob van Wijk -

  1. если запрос зависит от порядка столбцов;
  2. отсутствие ясности для последующих изменений в коде
  3. неиспользование индексов.
  4. Я не знал об отслеживании зависимостей на уровне столбцов, упомянутом Робом, и имел в виду, что, если в столбец было внесено изменение, это может сделать код недействительным (извлечение дополнительных столбцов вызывает переполнение, или запрос зависит от наличие определенного столбца.

Эти непредвиденные последствия вместе являются причиной упомянутых проблем с обслуживанием.

1 голос
/ 10 февраля 2012

SELECT * проблематично, если запрос зависит от порядка или количества столбцов, например:

INSERT INTO X (A, B)
SELECT * FROM T
WHERE B.NR = 113

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

1 голос
/ 10 февраля 2012

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

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