EXPLAIN ANALYZE в PL/pgSQL выдает ошибку: запрос не имеет назначения для данных результата

Я пытаюсь понять план запроса для оператора select в функции PL/pgSQL, но постоянно получаю ошибки. Мой вопрос: как мне получить план запроса?

Ниже приведен простой случай, который воспроизводит проблему.

Рассматриваемая таблица называется test_table.

CREATE TABLE test_table
(
  name character varying,
  id integer
);

Функция выглядит следующим образом:

DROP FUNCTION IF EXISTS test_function_1(INTEGER);
CREATE OR REPLACE FUNCTION test_function_1(inId INTEGER) 
RETURNS TABLE(outName varchar)
AS 
$$
BEGIN
  -- is there a way to get the explain analyze output?
  explain analyze select t.name from test_table t where t.id = inId;

  -- return query select t.name from test_table t where t.id = inId;
END;
$$ LANGUAGE plpgsql;

Когда я бегу

select * from test_function_1(10);

Я получаю сообщение об ошибке:

ERROR:  query has no destination for result data
CONTEXT:  PL/pgSQL function test_function_1(integer) line 3 at SQL statement

Функция работает нормально, если я раскомментирую закомментированную часть и закомментирую объяснение анализа.


person ARV    schedule 28.02.2014    source источник


Ответы (3)



Любой запрос должен иметь известную цель в plpgsql (иначе вы можете отбросить результат с помощью оператора PERFORM). Итак, вы можете сделать:

CREATE OR REPLACE FUNCTION fx(text)
RETURNS void AS $$
DECLARE t text;
BEGIN
  FOR t IN EXPLAIN ANALYZE SELECT * FROM foo WHERE v = $1
  LOOP
    RAISE NOTICE '%', t;
  END LOOP;
END;
$$ LANGUAGE plpgsql;
postgres=# SELECT fx('1');
NOTICE:  Seq Scan on foo  (cost=0.00..1.18 rows=1 width=3) (actual time=0.024..0.024 rows=0 loops=1)
NOTICE:    Filter: ((v)::text = '1'::text)
NOTICE:    Rows Removed by Filter: 14
NOTICE:  Planning time: 0.103 ms
NOTICE:  Total runtime: 0.065 ms
 fx 
────

(1 row)

Еще одна возможность получить план для встроенного SQL — использовать подготовленный оператор:

postgres=# PREPARE xx(text) AS SELECT * FROM foo WHERE v = $1;
PREPARE
Time: 0.810 ms

postgres=# EXPLAIN ANALYZE EXECUTE xx('1');
                                         QUERY PLAN                                          
─────────────────────────────────────────────────────────────────────────────────────────────
 Seq Scan on foo  (cost=0.00..1.18 rows=1 width=3) (actual time=0.030..0.030 rows=0 loops=1)
   Filter: ((v)::text = '1'::text)
   Rows Removed by Filter: 14
 Total runtime: 0.083 ms
(4 rows)
person Pavel Stehule    schedule 28.02.2014

Вы можете взглянуть на http://www.postgresql.org/docs/current/static/auto-explain.html и записать объяснение в файл журнала.

Также посмотрите, делает ли это то, что вы хотите. https://github.com/pgexperts/explanation

person Kuberchaun    schedule 28.02.2014
comment
Это (auto_explain) работает, но требует немного больше усилий, чем принятое решение в моем случае. Спасибо за ваш ответ (не знаю, почему за вас проголосовали!). - person ARV; 28.02.2014