Sql Postgres-获取分配给变量的查询成本

Sql Postgres-获取分配给变量的查询成本,sql,postgresql,postgresql-9.1,Sql,Postgresql,Postgresql 9.1,为了获得查询的估计成本,我使用EXPLAIN SELECT column FROM table;,为了获得查询的当前成本,我使用EXPLAIN analysis SELECT column FROM table;,我的问题是如何自动获取查询的成本,而不必手动为每个查询运行解释 我需要像这样的东西: DECLARE cost integer; DECLARE highercost integer; DECLARE query text; highercost := 0; i := 0; quer

为了获得查询的估计成本,我使用EXPLAIN SELECT column FROM table;,为了获得查询的当前成本,我使用EXPLAIN analysis SELECT column FROM table;,我的问题是如何自动获取查询的成本,而不必手动为每个查询运行解释

我需要像这样的东西:

DECLARE cost integer;
DECLARE highercost integer;
DECLARE query text;

highercost := 0;
i := 0;
query = '';

WHILE i < array_length( queryarray ,1) LOOP

    cost := explain analyse queryarray[i];

    IF cost > highercost THEN

        highercost := cost;
        query := queryarray[i];

    END IF;

    i := i+1;

END LOOP;
其想法是创建一个脚本来检查日志中的查询并在psql中运行,或者将日志查询复制到数据库中的一个表中并使用普通SQL运行以验证最昂贵的查询,目前这正是我所寻求的,无需担心查询的实际成本每分钟执行X次,插入、更新的成本,以及删除其他内容

我希望这是可能的,如果不是,有另一种方法来搜索昂贵的查询,而不必逐个检查

编辑:


忘了提一下,我正在使用Postgres 9.1。

也许您可以创建一个类似于以下内容的函数:

CREATE OR REPLACE FUNCTION query_cost(
      queries text[],
      query OUT text, cost OUT float8, duration OUT float8
   ) RETURNS SETOF record LANGUAGE plpgsql STRICT AS
$$DECLARE
   i integer;
   p json;
BEGIN
   /* loop through input queries */
   FOR i IN array_lower(queries, 1)..array_upper(queries, 1) LOOP
      query := queries[i];
      /* get execution plan in JSON */
      EXECUTE 'EXPLAIN (ANALYZE, FORMAT JSON) ' || query INTO p;
      /* extract total cost and execution time */
      SELECT p->0->'Plan'->>'Total Cost',
             p->0->'Plan'->>'Actual Total Time'
         INTO cost, duration;
      /* return query, cost and duration */
      RETURN NEXT;
   END LOOP;
END;$$;
您可以这样使用它:

SELECT *
FROM query_cost(
        ARRAY[
           'SELECT 42',
           'SELECT count(*) FROM large'
        ]
     )
ORDER BY duration DESC;

┌────────────────────────────┬─────────┬──────────┐
│           query            │  cost   │ duration │
├────────────────────────────┼─────────┼──────────┤
│ SELECT count(*) FROM large │ 1693.01 │  150.171 │
│ SELECT 42                  │    0.01 │    0.002 │
└────────────────────────────┴─────────┴──────────┘
(2 rows)
基于此答案[:

结果


还有一个问题,我在使用$$时收到了一个错误,但这将得到解决。

请看一看使用EXPLAIN Analysis,FORMAT JSON的函数。@Laurenz,尽管我忘了提到,我使用的是Postgres 9.1。-错误:类型JSON不存在,那么您必须使用类似于我以前版本的东西。PostgreSQL 9.1同样不受支持当然可以。这只适用于最后一步是聚合的查询,但也许这就是您所需要的。@Laurenz Albe True,没有意识到这一点,我将尝试使用JSON格式
CREATE or REPLACE function custo_consulta(_consulta text[])
returns table (consulta text, custo_execucao numeric, tempo_execucao numeric ) as '
declare custo text;
begin
    foreach consulta in array _consulta loop
        execute ''EXPLAIN ( FORMAT JSON, ANALYZE ) '' || consulta INTO custo;
        custo_execucao := split_part(split_part(custo, ''"Total Cost": '', 2), '','', 1);
        tempo_execucao := split_part(split_part(custo, ''"Actual Total Time": '', 2), '','', 1);
        return next;
    end loop;
end;
' language plpgsql;

SELECT *
FROM custo_consulta(array['SELECT COUNT(*) FROM syo_evento WHERE id_grupoevento = ''OPORTUNIDADE''', 'SELECT COUNT(*) FROM syo_evento WHERE id_grupoevento = ''REVISAO'''])
ORDER BY custo_execucao desc;
 consulta                                                               custo_execucao     tempo_execucao    
 SELECT COUNT(*) FROM syo_evento WHERE id_grupoevento = 'REVISAO'       38426,44           128,267           
 SELECT COUNT(*) FROM syo_evento WHERE id_grupoevento = 'OPORTUNIDADE'  38252,65           123,996