Положить результаты EXPLAIN в таблицу? - PullRequest
4 голосов
/ 07 октября 2011

Я вижу из документов Postgres 8.1 , что EXPLAIN генерирует что-то вроде табличных данных:

До PostgreSQL 7.3 план был выпущен в форме УВЕДОМЛЕНИЯ сообщение. Теперь он отображается как результат запроса (отформатированный как таблица с один текстовый столбец).

Я работаю с 9.0, для которой, скажем, docs , выходные данные могут быть различных типов, включая TEXT и XML. Что я действительно хотел бы сделать, так это обработать вывод как стандартный результат запроса, чтобы я мог сгенерировать простой отчет для запроса или набора запросов, например,

SELECT maxcost FROM (
    EXPLAIN VERBOSE 
    SELECT COUNT(*) 
      FROM Mytable
     WHERE value>17);

Вышеупомянутое не работает ни в какой форме, которую я пробовал, и я составил атрибут maxcost, чтобы продемонстрировать, насколько аккуратно было бы извлекать определенные биты данных (в данном случае это максимальная оценочная стоимость запроса). Есть ли что-нибудь, что я могу сделать, чтобы я был частью пути? Я предпочел бы иметь возможность работать в простой консоли SQL.

Ответы [ 2 ]

1 голос
/ 12 августа 2015

В этом сообщении предлагается использовать "FOR rec IN EXECUTE EXPLAIN ...", что, похоже, помогает, например ::

drop table if exists temp_a;
create temp table temp_a
(
    "QUERY PLAN" text
);


DO
$$
DECLARE
rec record;
BEGIN

FOR rec IN EXECUTE 'EXPLAIN VERBOSE select version()' 
LOOP
--  RAISE NOTICE 'rec=%', row_to_json(rec);

    insert into temp_a
    select rec."QUERY PLAN";
END LOOP;

END
$$ language plpgsql;

select *
from temp_a;
1 голос
/ 07 октября 2011

Других ответов пока нет, поэтому вот мой собственный ответ.

Можно прочитать результаты объяснения в переменную внутри plpgsql, и поскольку выходные данные могут быть в формате XML, можно поместить EXPLAIN в хранимую функцию, чтобы получить затраты верхнего уровня, используя xpath:

CREATE OR REPLACE FUNCTION estimate_cost(IN query text, 
OUT startup numeric,
OUT totalcost numeric, 
OUT planrows numeric, 
OUT planwidth numeric)
AS
$BODY$
DECLARE
    query_explain  text;
    explanation       xml;
    nsarray text[][];
BEGIN
nsarray := ARRAY[ARRAY['x', 'http://www.postgresql.org/2009/explain']];
query_explain :=e'EXPLAIN(FORMAT XML) ' || query;
EXECUTE query_explain INTO explanation;
startup := (xpath('/x:explain/x:Query/x:Plan/x:Startup-Cost/text()', explanation, nsarray))[1];
totalcost := (xpath('/x:explain/x:Query/x:Plan/x:Total-Cost/text()', explanation, nsarray))[1];
planrows := (xpath('/x:explain/x:Query/x:Plan/x:Plan-Rows/text()', explanation, nsarray))[1];
planwidth := (xpath('/x:explain/x:Query/x:Plan/x:Plan-Width/text()', explanation, nsarray))[1];
RETURN;
END;
$BODY$
LANGUAGE plpgsql;

Отсюда и пример из вопроса:

SELECT totalcost
FROM estimate_cost('SELECT COUNT(*) 
      FROM Mytable
     WHERE value>17');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...