PostgreSQL 慢 DISTINCT WHERE

标签 postgresql distinct where-clause

想象下表:

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;

我不确定是因为大小(它有 900 万行!)还是我效率低下,但查询花费的时间太长,用户无法有效地使用它。在我写这篇文章的时候,上面的查询花了我 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 上建立了索引。

最佳答案

您的 40 秒用于顺序读取整个表格,丢弃 3113338 行,仅保留 19129 行。

补救措施很简单:

CREATE INDEX ON drops(tag);

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

改变查询中的条件从

WHERE tag = '1'

WHERE tag = 1

它恰好有效,因为 '1' 是文字,但不要尝试比较字符串和数字。

并且,如前所述,保留 DISTINCTGROUP BY,但不能同时保留两者。

关于PostgreSQL 慢 DISTINCT WHERE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54778804/

相关文章:

SQL Group by 具有聚合和不同

SQL如何有效地使用wheresomething!=something?

sql - 使用 HAVING 还是 WHERE?

MySQL JOIN+WHERE 没有给出结果

mysql - 存储长二进制(原始数据)字符串

postgresql - Postgresql - 将聚合、逗号分隔值拆分为查询内的单独列 - 使用 Amazon Aws 和 PostgreSql 9.6

php - 在另一列不同的情况下对另一列的值求和

sql - 使用 with 子句消除具有空值的重复行

php - PDO 不抛出未绑定(bind)参数的异常(并且查询中没有变量)

sql - "plan should not reference subplan' s变量“错误