Reputation: 46
How to speed up the search in a PostgreSQL database? There are three tables: table_a, table_b, table_c. Problem that table_a has 450 000
records, table_b has 8 300 000
records, table_c has 1 180 000
records.
This query has to wait for about 15 minutes:
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
The number of rows may not exceed 500. When I set a limit of up to 500, the query time becomes within 1 second.
Create info:
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
)
Additional info:
Upvotes: 0
Views: 364
Reputation: 1271151
First, the left join
s are not needed because the where
clause turns them into inner joins anyway. So rewrite the query as:
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;
Then the following indexes should help: table_a(id)
, table_b(table_a_id, id)
, and table_c(table_b.b_id)
.
Actually, the query can be simplified, because the table_a
id is in 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;
The first index is not needed for this query.
Finally, if this query might return duplicates and you do not want them, then you might consider:
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
);
Upvotes: 1