Присвойте значения с: = оператор

Когда я присваиваю переменную с

result := title || '', by '' || author;

требуется больше времени (приблизительно 15 секунд) для выполнения функции.
Однако, когда я присваиваю переменную с

result = title || '', by '' || author;

требуется только 133 мс.

Почему требуется больше времени для первого сценария? И какова причина позади этого?

Полная функция дана ниже.

CREATE OR REPLACE FUNCTION myschema.fn_get_res_no(reservation_no character varying)
  RETURNS character varying AS
$BODY$  

DECLARE  
    emd_status_firstcall varchar(2);  
    emd_status_secondcall varchar(2);
    emd_status      varchar(6);  
BEGIN  
    SELECT firstwscomplete, secondwscomplete
    INTO emd_status_firstcall, emd_status_secondcall
    FROM myschema.mytable
    WHERE respkgconfirmid = reservation_no;

    emd_status = emd_status_firstcall || ', ' || emd_status_secondcall;
    RETURN emd_status ;  

END;  
$BODY$
  LANGUAGE plpgsql VOLATILE;
3
08.01.2020, 00:25
2 ответа

Этот вопрос касается PL/pgSQL исключительно, где := оператор присваивания. Это не имеет никакого места в чистом SQL.

Используя = вместо := в PL/pgSQL недокументированная функция прежней версии, которая не должна быть использована.
:= зарегистрированный оператор присваивания в PL/pgSQL..
Больше деталей об этом в этом связанном вопросе на ТАК.

Обновление: начиная с пост-ГРЭС 9.4 = также документируется как plpgsql assignement оператор.

Я никогда не видел = выполнение быстрее, чем :=. Они должны быть идентичными. Я факт, я протестировал Ваш точный код в Пост-ГРЭС 9.1 и 9.2 и не нашел разницы в производительности вообще.
Можно неправильно истолковывать кэширующиеся эффекты. Всегда выполняемый EXPLAIN ANALYZE пару раз заполнить кэш и получить сопоставимые результаты.

Наконец, Вы могли заменить свою функцию этой намного более простой и более быстрой:

CREATE OR REPLACE FUNCTION myschema.fn_get_res_no(reservation_no varchar)
  RETURNS varchar AS
$BODY$  
BEGIN  
   RETURN (
      SELECT firstwscomplete || ', ' || secondwscomplete
      FROM   myschema.mytable
      WHERE  respkgconfirmid = reservation_no
      );
END  
$BODY$ LANGUAGE plpgsql;

Или даже используйте плоскость функция SQL:

CREATE OR REPLACE FUNCTION myschema.fn_get_res_no(reservation_no varchar)
  RETURNS varchar AS
$BODY$  
   SELECT firstwscomplete || ', ' || secondwscomplete
   FROM   myschema.mytable
   WHERE  respkgconfirmid = reservation_no);
$BODY$
  LANGUAGE sql;

Присвоения в PL/pgSQL

Сравнительно дорого сделать присвоения в PL/pgSQL, который является очень простым подобным Ada процедурным языком. Каждое присвоение выполняется с (очень простой) командой SELECT, которая является более дорогой, чем на других полностью оперенных процедурных языках.

PL/pgSQL выделяется, как связующее звено для SQL управляет при необходимости в некоторых процедурных элементах.

5
22.02.2020, 22:51
  • 1
    Привет Erwin, спасибо за комментарии. Однако я сталкиваюсь с этой проблемой в PostgreSQL 8.2. Интересно эта проблема была устранена в более новых версиях. –  kds 11.09.2013, 07:44
  • 2
    @kds: существует очень длинный список вещей, которые были починены начиная с Пост-ГРЭС 8.2. Я настоятельно рекомендую, чтобы Вы нашли способ обновить до текущей версии Пост-ГРЭС. Рассмотрите политику управления версиями. В следующий раз также не забудьте предоставлять своему номеру версии Ваш вопрос. –  Erwin Brandstetter 11.09.2013, 14:34

Хорошо насколько я знаю "=", не оператор присваивания в PL/pgSQL, это - оператор сравнения. Если бы это не объясняет проблему затем, мы лучше всего видели бы полный код.

0
22.02.2020, 22:51
  • 1
    Привет, я включил полную функцию к исходному вопросу. –  kds 09.09.2013, 15:13

Теги

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