Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql 使用Limit和HashAggregates的慢速查询_Postgresql_Database Performance - Fatal编程技术网

Postgresql 使用Limit和HashAggregates的慢速查询

Postgresql 使用Limit和HashAggregates的慢速查询,postgresql,database-performance,Postgresql,Database Performance,博士后9.3 在下面的示例查询中,为什么HashAggregate会处理1000万行(在5s内),而不是在收集到限制指定的1行(应该少于1ms)后立即停止 我在很多有限的问题上都有类似的问题。。。HashAggregate使有限查询与无限查询花费的时间一样长。。。这使得限制完全无用 在收集了n行之后,是否存在无法停止的原因 创建一些测试数据: create table foo (x integer); insert into foo (x) (select * from generate_ser

博士后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(生成相同的查询计划!):

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

当考虑您的示例时,考虑DB将如何确定要显示的结果(限制1)。它必须执行某种排序。我假设您的实际示例将包含一个limit>1,但我认为他们使用limit 1,那么有许多方法可以重写查询以利用其有限的行。

在使用“order by”、“distinct”或聚合函数的查询中,必须收集、排序整个查询结果,并在可以应用限制之前进行聚合(无论限制数量如何)。您可以通过多种方式重写查询,以获得相同的结果,但速度更快。然而,我需要看到更逼真的查询,因为示例对于实际用例来说并不太现实


当考虑您的示例时,考虑DB将如何确定要显示的结果(限制1)。它必须执行某种排序。我假设您的实际示例将包含一个limit>1,但我假设他们使用limit 1,那么有很多方法可以重写查询以利用其有限的行。

rows=200部分只是未分析的表中的估计值。您的示例几乎没有意义。可简化为
从foo limit 1中选择x和Postgres在为此收集1行后停止。也许您可以提供一个带有真实问题的测试用例(如果有问题的话)?@ErwinBrandstetter将“groupby”替换为“distinct”。。这将产生完全相同的查询计划。为什么需要5秒才能找到第一行?这有意义吗?
rows=200
部分只是一个未经分析的表中的估计值。您的示例几乎没有意义。可简化为
从foo limit 1中选择x和Postgres在为此收集1行后停止。也许您可以提供一个带有真实问题的测试用例(如果有问题的话)?@ErwinBrandstetter将“groupby”替换为“distinct”。。这将产生完全相同的查询计划。为什么需要5秒才能找到第一行?这有意义吗?为什么distinct必须收集整个查询结果,而它应该只返回n个不同的值?前两个不同的值3,3,1,2,3,。。。值为3和1(这足以查看前三个值)。“它必须执行某种类型的操作”-不。在我发布的查询计划中,显然没有发生排序。。HashAggregates不需要它。@stmax假设您的查询限制为100000000,而不是1。首先,它必须获得所有不同的值(这涉及到遍历每一行以找到不同的值),然后限制这些值。这个问题不仅出现在不同的查询、分组查询中,而且还出现在包含函数的查询中(从y限制1中选择一些函数(x))。事实上,我向黑客组织提交了一个优化这些问题的请求,但是,它显然违反了常见的sql约定,可能有副作用,所以被拒绝了。你能发布一个链接,解释这将打破什么“常见sql约定”吗?thanksTom Lane,在这个线程中说它打破了SQL计算模型,我没有到源代码的链接。有趣的阅读,将不得不考虑更多,谢谢。为什么distinct必须收集整个查询结果,而它应该只返回n个distinct值?前两个不同的值3,3,1,2,3,。。。值为3和1(这足以查看前三个值)。“它必须执行某种类型的操作”-不。在我发布的查询计划中,显然没有发生排序。。HashAggregates不需要它。@stmax假设您的查询限制为100000000,而不是1。首先,它必须获得所有不同的值(这涉及到遍历每一行以找到不同的值),然后限制这些值。这个问题不仅出现在不同的查询、分组查询中,而且还出现在包含函数的查询中(从y限制1中选择一些函数(x))。事实上,我向黑客组织提交了一个优化这些问题的请求,但是,它显然违反了常见的sql约定,可能有副作用,所以被拒绝了。你能发布一个链接,解释这将打破什么“常见sql约定”吗?thanksTom Lane,在这个帖子中说它打破了SQL计算模型,我没有到源代码的链接。有趣的阅读,将不得不考虑更多,谢谢。
explain analyze
select distinct x from foo limit 1;
 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