Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.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
Performance postgresql计数(不同…)非常慢_Performance_Postgresql_Count_Distinct - Fatal编程技术网

Performance postgresql计数(不同…)非常慢

Performance postgresql计数(不同…)非常慢,performance,postgresql,count,distinct,Performance,Postgresql,Count,Distinct,我有一个非常简单的SQL查询: SELECT COUNT(DISTINCT x) FROM table; 我的表大约有150万行。这个查询运行得非常慢;与之相比,大约需要7.5秒 SELECT COUNT(x) FROM table; 大约需要435ms。有没有办法更改我的查询以提高性能?我尝试过分组和进行常规计数,以及在x上建立索引;两者都有相同的7.5s执行时间 -- My default settings (this is basically a single-session mac

我有一个非常简单的SQL查询:

SELECT COUNT(DISTINCT x) FROM table;
我的表大约有150万行。这个查询运行得非常慢;与之相比,大约需要7.5秒

 SELECT COUNT(x) FROM table;
大约需要435ms。有没有办法更改我的查询以提高性能?我尝试过分组和进行常规计数,以及在x上建立索引;两者都有相同的7.5s执行时间

-- My default settings (this is basically a single-session machine, so work_mem is pretty high)
SET effective_cache_size='2048MB';
SET work_mem='16MB';

\echo original
EXPLAIN ANALYZE
SELECT
        COUNT (distinct val) as aantal
FROM one
        ;

\echo group by+count(*)
EXPLAIN ANALYZE
SELECT
        distinct val
       -- , COUNT(*)
FROM one
GROUP BY val;

\echo with CTE
EXPLAIN ANALYZE
WITH agg AS (
    SELECT distinct val
    FROM one
    GROUP BY val
    )
SELECT COUNT (*) as aantal
FROM agg
        ;
结果:

original                                                      QUERY PLAN                                                      
----------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=36448.06..36448.07 rows=1 width=4) (actual time=1766.472..1766.472 rows=1 loops=1)
   ->  Seq Scan on one  (cost=0.00..32698.45 rows=1499845 width=4) (actual time=31.371..185.914 rows=1499845 loops=1)
 Total runtime: 1766.642 ms
(3 rows)

group by+count(*)
                                                         QUERY PLAN                                                         
----------------------------------------------------------------------------------------------------------------------------
 HashAggregate  (cost=36464.31..36477.31 rows=1300 width=4) (actual time=412.470..412.598 rows=1300 loops=1)
   ->  HashAggregate  (cost=36448.06..36461.06 rows=1300 width=4) (actual time=412.066..412.203 rows=1300 loops=1)
         ->  Seq Scan on one  (cost=0.00..32698.45 rows=1499845 width=4) (actual time=26.134..166.846 rows=1499845 loops=1)
 Total runtime: 412.686 ms
(4 rows)

with CTE
                                                             QUERY PLAN                                                             
------------------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=36506.56..36506.57 rows=1 width=0) (actual time=408.239..408.239 rows=1 loops=1)
   CTE agg
     ->  HashAggregate  (cost=36464.31..36477.31 rows=1300 width=4) (actual time=407.704..407.847 rows=1300 loops=1)
           ->  HashAggregate  (cost=36448.06..36461.06 rows=1300 width=4) (actual time=407.320..407.467 rows=1300 loops=1)
                 ->  Seq Scan on one  (cost=0.00..32698.45 rows=1499845 width=4) (actual time=24.321..165.256 rows=1499845 loops=1)
       ->  CTE Scan on agg  (cost=0.00..26.00 rows=1300 width=0) (actual time=407.707..408.154 rows=1300 loops=1)
     Total runtime: 408.300 ms
    (7 rows)
与CTE相同的计划也可能由其他方法窗口函数生成

如果您的countdistinctx明显慢于countx,那么您可以通过在不同的表中维护x值计数来加速此查询,例如,使用触发器来维护表_name_x_counts x integer not null,x_count int not null。但您的写入性能将受到影响,如果在单个事务中更新多个x值,则需要以明确的顺序执行此操作,以避免可能的死锁。

您可以使用以下方法:

SELECT COUNT(*) FROM (SELECT DISTINCT column_name FROM table_name) AS temp;
这比:

COUNT(DISTINCT column_name)

我也在搜索相同的答案,因为在某个时间点,我需要具有不同值的total_count以及limit/offset

因为这样做有点棘手-获得具有不同值的总计数以及限制/偏移。通常很难通过限制/偏移获得总计数。最后我终于找到了方法-

选择DISTINCT COUNT*OVER作为总计数,*来自表\u name limit 2偏移量0


查询性能也很高。

从coluna的tabela group中选择coluna,countcoluna作为qtd,我不这么认为。获取150万行的不同值会很慢。我刚刚在C中尝试过,从内存中获取150万个整数的不同值需要在我的计算机上花费一秒钟的时间。因此,我认为您可能运气不好。查询计划将在很大程度上取决于表结构索引和调优常量workmem、有效缓存大小、随机页面成本的设置。通过合理的调整,查询可能会在不到一秒钟的时间内执行。您能更具体一点吗?需要什么索引和调优常量才能在一秒钟内得到它?为简单起见,假设这是一个两列的表,第一列y上有一个主键,我正在对int类型的第二列x执行“distinct”查询,该列有150万行。请将表定义包含在所有索引中\d psql的输出是一个好的输出,精确到您遇到问题的列。最好看看这两个查询的解释和分析。您考虑过缓存的影响吗?如果随后执行三个解释分析,第一个可能是从磁盘缓慢获取内容,而后两个可能是从内存快速获取内容。事实上:有效缓存大小是第一个需要调整的设置。我的是2GB,IIRC。我将有效缓存大小设置为2GB,性能不变。您建议调整其他设置吗?如果是的话,是什么?1你是如何设定的?你把它弄脏了吗?你真的有那么多可用内存吗?让我们看看你的计划。4也许我的机器更快,或者你的机器有更多的并发负载需要处理@ferson2020:OkI用以下语句设置它:set effective_cache_size='2GB';我确实有那么多可用的内存。我试着包括我的查询计划,但它不适合在评论框中。神圣的查询蝙蝠侠!这使我的博士后人数从190人增加到了4.5人哇!我找到了这个讨论相同内容的线程:。Jeff Janes的一个回复说COUNTDISTINCT对表进行排序以完成其工作,而不是使用哈希。@Ankur我可以问你一个问题吗?由于COUNTDISTINCT执行排序,因此在列名上有一个索引肯定会有帮助,尤其是在工作量相对较小的情况下,哈希将产生相对较大的批。既然如此,使用COUNT DISTINCT并不总是坏事,不是吗?@musmahn Countcolumn只计算非空值。计数*对行进行计数。因此,第一个/更长的行也将对空行计数一次。更改为countcolumn\u name以使它们的行为相同。@ankur这对我没有多大用处。.没有得到任何显著的改进。