PostgreSQL慢的地方

时间:2019-02-20 04:22:40

标签: postgresql distinct where

想象一下下表:

CREATE TABLE drops(
    id BIGSERIAL PRIMARY KEY,
    loc VARCHAR(5) NOT NULL,
    tag INT NOT NULL
);

我想做的是执行查询,在其中可以找到值与标记匹配的所有唯一位置。

SELECT DISTINCT loc
FROM drops
WHERE tag = '1'
GROUP BY loc;

我不确定这是由于大小(9m行大!)还是效率低下引起的,但是查询花费的时间太长,用户无法有效使用它。在我撰写本文时,上面的查询花了我1:14分钟。

我可以使用任何技巧或方法将其缩短到几秒钟吗?

非常感谢!

执行计划:

"Unique  (cost=1967352.72..1967407.22 rows=41 width=4) (actual time=40890.768..40894.984 rows=30 loops=1)"
"  ->  Group  (cost=1967352.72..1967407.12 rows=41 width=4) (actual time=40890.767..40894.972 rows=30 loops=1)"
"        Group Key: loc"
"        ->  Gather Merge  (cost=1967352.72..1967406.92 rows=82 width=4) (actual time=40890.765..40895.031 rows=88 loops=1)"
"              Workers Planned: 2"
"              Workers Launched: 2"
"              ->  Group  (cost=1966352.70..1966397.43 rows=41 width=4) (actual time=40879.910..40883.362 rows=29 loops=3)"
"                    Group Key: loc"
"                    ->  Sort  (cost=1966352.70..1966375.06 rows=8946 width=4) (actual time=40879.907..40881.154 rows=19129 loops=3)"
"                          Sort Key: loc"
"                          Sort Method: quicksort  Memory: 1660kB"
"                          ->  Parallel Seq Scan on drops  (cost=0.00..1965765.53 rows=8946 width=4) (actual time=1.341..40858.553 rows=19129 loops=3)"
"                                Filter: (tag = 1)"
"                                Rows Removed by Filter: 3113338"
"Planning time: 0.146 ms"
"Execution time: 40895.280 ms"

该表在loctag上建立索引。

2 个答案:

答案 0 :(得分:1)

您花了40秒钟顺序读取整个表,扔掉了3113338行,仅保留19129行。

解决方法很简单:

CREATE INDEX ON drops(tag);

但是您说您已经做到了,但是我很难相信。您使用的命令是什么?

从以下位置更改查询中的条件

WHERE tag = '1'

WHERE tag = 1

之所以起作用,是因为'1'是一个文字,但是不要尝试比较字符串和数字。

并且如上所述,请保留DISTINCTGROUP BY,但不要同时保留两者。

答案 1 :(得分:0)

如果您使用了GROUP BY子句,则无需使用DISTINCT关键字。省略该设置可以加快查询的运行时间。