Процедурные языки PostgreSQL - различия между PL / pgSQL и SQL

20

Кто-нибудь может, пожалуйста, суммировать различия между:

http://www.postgresql.org/docs/9.1/static/xfunc-sql.html

и

http://www.postgresql.org/docs/9.1/static/plpgsql.html

?

Основные положения:

  • концептуальные различия
  • учитывая проблемную семью, удобство использования
  • политические вопросы
Джисмо Ранас
источник
1
Во-первых, функции SQL (он же язык запросов) не используют процедурный язык PostgreSQL. Во-вторых, вы уже нашли лучший источник, где можно найти ответы на ваши вопросы (за исключением последнего - что именно вы подразумеваете под «политическими вопросами»?)
dezso
Я попросил обобщить все основные вопросы, не обязательно используя документацию, которую я вставил, но также используя личные впечатления. Эти ссылки существуют только для того, чтобы убедиться, что все понимают, о чем идет речь.
Джисмо Ранас
Не воспринимайте это как нападение, но как только вы прочтете их, вы сможете обобщить их самостоятельно :) В противном случае ваш вопрос будет довольно широким, но если уделить немного времени, я постараюсь собраться с мыслями.
Дезсо
1
Не пренебрегайте другими процедурными языками. В частности, PL / Perl чрезвычайно полезен для областей, где PL / PgSQL слишком ограничен; PL / Pythonu делает эту работу, если вы предпочитаете Python, но не предлагаете такую ​​модель безопасности, как PL / Perl. Также есть PL / V8 (JavaScript) в качестве дополнения.
Крейг Рингер
1
Привет, cataldo. Я просто хотел бы поприветствовать вас на сайте, так как это ваш первый вопрос здесь. Спасибо за публикацию, и я надеюсь, что вы остаетесь.
Джек Дуглас

Ответы:

27

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

  • Используйте представления, где это возможно
  • Там, где представление не подходит, используйте функцию SQL
  • Если функция SQL не подходит, используйте PL / PgSQL.
  • Там, где PL / PgSQL слишком ограничен или недостаточно выразителен, используйте PL / Perl, PL / Python, PL / V8, PL / Java, или как вы предпочитаете
  • ... и там, где ни один PL не будет выполнять работу, использовать внешнюю программу и, возможно, LISTENи NOTIFYпоговорить с ней.

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

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

  • Необходимы параметры, которые не могут быть выражены в виде простых WHEREпредложений, например, параметр в WITHвыражении
  • Вам нужен защитный барьер через SECURITY DEFINERфункцию, и security_barrierпредставления в PostgreSQL 9.2 и выше не подходят для ваших нужд;
  • Вам нужны параметры, которые не помещаются оптимизатором в подпункты представления, и вы хотите управлять им более непосредственно; или
  • Есть много параметров или много повторений параметров, поэтому нецелесообразно писать запрос как представление.

Для большинства из этих задач простая функция SQL работает нормально, и ее часто легче читать, чем PL / PgSQL. Функции SQL, объявленные STABLEили IMMUTABLE(и не объявленные STRICTили SECURITY DEFINER), также могут быть встроены в вызывающий оператор. Это избавляет от накладных расходов, связанных с вызовом функции, и иногда может привести к огромным выигрышам в производительности, когда условие WHERE в вызывающей функции помещается оптимизатором в функцию SQL. Используйте функции SQL всякий раз, когда они достаточны для задачи.

Основное время, когда функции SQL не справляются с этой задачей, - это когда вам нужно много логики. Если / то / еще операции, которые вы не можете выразить как CASEоператоры, многократное использование вычисленных результатов, построение значений на основе кусков, обработка ошибок и т. Д. PL / PgSQL пригодится тогда. Выбирайте PL / PgSQL, когда вы не можете использовать функции SQL или они плохо подходят, например, для:

  • Динамический SQL и динамический DDL через EXECUTEоператор
  • Когда вы хотите, чтобы RAISEошибки / предупреждения для журналов или клиента
  • Когда вам нужна обработка исключений - вы можете перехватывать и обрабатывать ошибки с EXCEPTIONблоками, вместо того, чтобы вся транзакция завершалась при ошибке
  • Сложная условная логика, которая не CASE ... WHENочень хорошо подходит
  • Много повторного использования вычисленных значений, которые вы не можете вписать в WITHCTE и
  • Построение динамических записей
  • Вам необходимо выполнить действие после создания набора результатов

С общими табличными выражениями (CTE), особенно написанными CTE, и WITH RECURSIVEя обнаружил, что я использую PL / PgSQL гораздо меньше, чем раньше, потому что SQL намного более выразителен и мощен. Сейчас я использую представления и простые функции SQL гораздо чаще. Стоит помнить, что простые функции SQL могут содержать более одного оператора; последнее утверждение является результатом функции.

Крейг Рингер
источник
Очень хорошо сказано! (дополнительный виртуальный +1 за упоминание доступных для записи CTE)
dezso
Этот ответ также объясняет, почему некоторые функции нуждаются в оптимизации .
Эонил
8

plpgsqlявляется полноценным процедурным языком с переменными, циклическими конструкциями и т. д. SQLФункция - это просто подзапрос. Функция SQL, если она объявлена STABLEили IMMUTABLEне объявлена STRICT, часто может быть встроена в вызывающий запрос, как если бы она была записана в каждой ссылке.

kgrittn
источник