加快在 PostgreSQL 中的搜索
Posted
技术标签:
【中文标题】加快在 PostgreSQL 中的搜索【英文标题】:Speed up the search in a PostgreSQL 【发布时间】:2020-09-05 05:46:24 【问题描述】:如何加快 PostgreSQL 数据库中的搜索速度?共有三个表:table_a、table_b、table_c。 table_a 有450 000
记录,table_b 有8 300 000
记录,table_c 有1 180 000
的问题
记录。
此查询需要等待大约 15 分钟:
select table_c.* from table_c
left join table_b on table_b.id = table_c.table_b_id
left join table_a on table_a.id = table_b.table_a_id
where table_a.id = 1
行数不能超过500。当我设置上限为500时,查询时间变成1秒以内。
创建信息:
CREATE TABLE table_a
(
id serial NOT NULL,
latitude numeric(10,8) NOT NULL,
longitude numeric(11,8) NOT NULL,
CONSTRAINT table_a_pkey PRIMARY KEY (id),
)
CREATE TABLE table_b
(
id serial NOT NULL,
table_a_id integer,
CONSTRAINT table_b_pkey PRIMARY KEY (id),
CONSTRAINT table_b_table_a_id_fkey FOREIGN KEY (table_a_id)
REFERENCES table_a (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
CREATE TABLE table_c
(
id serial NOT NULL,
table_b_id integer,
geom geometry(MultiPolygon,4326),
CONSTRAINT table_c_pkey PRIMARY KEY (id),
CONSTRAINT table_c_table_b_id_fkey FOREIGN KEY (table_b_id)
REFERENCES table_b (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
其他信息:
操作系统 Windows 7 内存 4 GB CPU 2 - 3Ghz Postgres 9.4.26 64 位【问题讨论】:
请edit您的问题并添加使用explain (analyze, buffers, format text)
生成的execution plan(不是只是一个“简单”解释)为formatted text,并确保保留计划的缩进。粘贴文本,然后将```
放在计划前一行和计划后一行。还请包括所有索引的完整create index
语句。最好先打开track_io_timing
(需要超级用户访问权限)
您可能需要考虑升级到受支持和维护的 Postgres 版本。 9.4 是no longer supported,自 2016 年以来性能也有了显着提升。一般来说,只有 4GB 的计算机并不适合用作数据库服务器(很可能还有慢速硬盘)。
@a_horse_with_no_name。缺少 indexex。创建的索引可以解决所有问题。谢谢。
【参考方案1】:
首先,不需要left join
s,因为where
子句无论如何都会将它们变成内部连接。所以将查询重写为:
select c.*
from table_c c join
table_b b
on b.id = c.table_b_id join
table_a a
on a.id = b.table_a_id
where a.id = 1;
那么以下索引应该会有所帮助:table_a(id)
、table_b(table_a_id, id)
和 table_c(table_b.b_id)
。
其实查询可以简化,因为table_a
的id在table_b
:
select c.*
from table_c c join
table_b b
on b.id = c.table_b_id
where b.table_a_id = 1;
此查询不需要第一个索引。
最后,如果此查询可能返回重复项并且您不想要它们,那么您可以考虑:
select c.*
from table_c c
where exists (select 1
from table_b b
where b.id = c.table_b_id and b.table_a_id = 1
);
【讨论】:
以上是关于加快在 PostgreSQL 中的搜索的主要内容,如果未能解决你的问题,请参考以下文章
postgres 错误:Postgresql 11.6 中的列不存在错误
Django trigram_similar搜索没有返回结果(带有Postgresql 10.5后端的Django 2.1)