【发布时间】:2020-12-03 16:31:17
【问题描述】:
我有一个product 表,它有一个索引 列manufacturer_id。该表有 30M 行。我想检查表中是否存在特定行。我使用的查询:
select exists(select 1 from product where manufacturer_id = '0');
select 1 from product where manufacturer_id = '0' fetch first row only;
select 1 from product where manufacturer_id = '0' limit 1;
每个查询需要 4 分钟。表中有 12M 行带有manufacturer_id = '0'。但是,如果我使用 manufacturer_id = '1234567'(表中有 2 行)运行相同的查询,它会在 250 毫秒内返回结果。
我希望检查行的存在不会花费很长时间。或者,我是不是弄错了,考虑到桌子的容量,花那么长时间是正常的?如果不正常,如何提高性能?
执行计划:
Result (cost=0.07..0.08 rows=1 width=1) (actual time=0.015..0.016 rows=1 loops=1)
Buffers: shared hit=1
InitPlan 1 (returns $0)
-> Seq Scan on product (cost=0.00..914306.95 rows=12306868 width=0) (actual time=0.014..0.014 rows=1 loops=1)
Filter: ((manufacturer_id)::text = '0'::text)
Buffers: shared hit=1
Planning Time: 0.093 ms
Execution Time: 0.036 ms
创建索引语句:(这是除主键之外的唯一索引)
create index product_manufacturer_id
on product (manufacturer_id);
manufacturer_id: varchar 类型和indexed 列。
Postgres 版本:12
【问题讨论】:
-
manufacturer_id是什么数据类型?如果那是int或bigint,则必须将其与数字进行比较。'1234567'是一个字符串,因此无法使用索引,请改用where manufacturer_id = 1234567。这在使用explain (analyze)生成的执行计划中很容易看到 -
该列是
varchar类型并且已经有一个index。我编辑了问题。 -
那么请edit您的问题并添加使用
explain (analyze, buffers, format text)生成的慢查询execution plan(not 只是一个“简单”的解释)作为formatted text 并确保保留计划的缩进。粘贴文本,然后将```放在计划前一行和计划后一行。还请包括所有索引的完整create index语句。 -
计划显示运行该查询需要 0.036 毫秒秒 - 这甚至比您提到的 4 分钟还差
-
请向我们展示表和索引的完整 ddl。加上解释分析
标签: sql database postgresql query-performance