带限制和HashAggregates的慢查询

时间:2013-11-21 18:16:39

标签: postgresql database-performance

Postgres 9.3

在下面的示例查询中,为什么HashAggregate处理1000万行(以5s为单位)而不是在收集限制指定的1行时停止(应该少于1ms)?

我遇到很多有限查询的问题... HashAggregate使用进行有限查询只要无限查询......这使得限制完全没用。

有没有理由为什么它在收集n行后无法停止?

创建一些测试数据:

create table foo (x integer);
insert into foo (x) (select * from generate_series(1, 10000000));

运行查询:

explain analyze
select x from foo group by x limit 1;

或使用distinct而不是group by(导致相同的查询计划!):

explain analyze
select distinct x from foo limit 1;

http://explain.depesz.com/s/arPX

 Limit  (cost=176992.00..176992.01 rows=1 width=4) (actual time=5185.125..5185.125 rows=1 loops=1)
   ->  HashAggregate  (cost=176992.00..176994.00 rows=200 width=4) (actual time=5185.124..5185.124 rows=1 loops=1)
         ->  Seq Scan on foo  (cost=0.00..150443.20 rows=10619520 width=4) (actual time=0.018..949.926 rows=10000000 loops=1)
 Total runtime: 5244.966 ms

1 个答案:

答案 0 :(得分:1)

在具有“order by”,“distinct”或聚合函数的查询中,必须先收集,排序和聚合整个查询结果,然后才能应用限制(无论限制数量如何)。您可以通过多种方式重写查询以获得相同的结果,但速度更快,但是,我需要查看更逼真的查询,因为该示例对于实际用例不太现实。

在考虑您的示例时,请考虑数据库如何确定要显示的结果(限制1)..它必须执行某种排序。我假设您的实际示例包含限制> 1,但我使用限制1,然后有很多方法可以重写查询以利用它们有限的行。