0

当我在查询下运行时

explain
select count(*) over() as t_totalcnt,  max(hits) over() as t_maxhits,  max(bytes) over() as t_maxbytes, * 
from 
(
    select category,sum(hits) as hits,sum(bytes) as bytes 
    from (
        select "5mintime",category,hits,bytes,appid, 0 as tmpfield
       from web_categoryutfv1_24hr_ts_201209 
       where "5mintime" >='2012-09-12 00:00:00' and "5mintime" < '2012-09-19 00:00:00'
    ) as tmp  
    where "5mintime" >='2012-09-12 00:00:00' 
    and "5mintime" <= '2012-09-18 23:59:59' 
    and appid in ('') group by category order by hits desc 
) as foo 
limit 10;

我得到以下输出

  Limit  (**cost=31.31..31.61** rows=10 width=580)
  ->  WindowAgg  (**cost=31.31..32.03** rows=24 width=580)   
  ->  Subquery Scan foo  (cost=31.31..31.61 rows=24 width=580)
     ->  Sort  (**cost=31.31..31.37** rows=24 width=31)
        Sort Key: (sum(web_categoryutfv1_24hr_ts_201209.hits))
               ->  HashAggregate  (**cost=30.39..30.75** rows=24 width=31)
                    ->  Seq Scan on web_categoryutfv1_24hr_ts_201209  (cost=0.00..27.60 rows=373 width=31)
            Filter: (("5mintime" >= '2012-09-12 00:00:00'::timestamp without time zone) 
                   AND ("5mintime" < '2012-09-19 00:00:00'::timestamp without time zone)
                   AND ("5mintime" >= '2012-09-12 00:00:00'::timestamp without time zone)
                   AND ("5mintime" <= '2012-09-18 23:59:59'::timestamp without time zone)
                   AND ((appid)::text = ''::text))

当我在没有解释标签的情况下运行上面的查询时。我在 1 秒内得到输出,而这里 cost=31.31..31.61。

任何人请帮我理解解释计划中的成本关键字是什么意思我的意思是解释计划中的成本关键字单位?

4

1 回答 1

1

成本是查询计划者对操作难度或执行所需时间的估计。它基于一些机器级参数——例如,磁盘查找与流式读取相比需要多长时间——以及表级信息,例如每行有多大、有多少行或值的分布在每一列。没有单位,产生的成本值是任意的。成本是 PostgreSQL 用来确定如何执行查询的指标;它将考虑执行查询的多种方式并选择成本最低的计划。有关成本计算的更多详细信息,请参阅Planner 成本约束

假设您使用的是默认设置,那么顺序扫描的成本如此之低表明 PostgreSQL 认为该表中的行数不多。运行需要整整一秒钟的事实表明,事实上,该表中有很多行。您可以通过说 告诉 PostgreSQL 收集有关该表的新统计信息ANALYZE web_categoryutfv1_24hr_ts_201209。无论如何,该pg_autovacuum过程应该定期收集统计信息,但也许您使用的是旧版本的 PostgreSQL,或者它有一段时间没有运行,或者谁知道;无论如何,再次手动操作并没有什么坏处。

如果 PostgreSQL 认为表很小,它会更喜欢顺序扫描而不是使用索引,因为整个表的顺序读取比索引扫描然后是一堆随机读取要快。另一方面,如果 PostgreSQL 认为表很大,那么在5mintimeand/or上引用索引可能会更快appid,假设所述索引将允许它排除许多行。如果您没有这样的索引,请考虑创建一个。

最后一件事:EXPLAIN有一个名叫EXPLAIN ANALYZE. 虽然EXPLAIN向您显示 PostgreSQL 将选择的查询计划以及指导其决策的成本,但EXPLAIN ANALYZE实际执行查询并向您显示每个组件运行多长时间。有关更多信息,请参见解释

于 2012-09-20T17:22:47.737 回答