如何优化此查询?
我想查找firms2branches
和project_id
中存在的firms
accounts_premium
之后的所有行。我的桌子:
-- 50000 rows
CREATE TABLE firms
(
id bigserial NOT NULL,
firm_id bigint NOT NULL,
CONSTRAINT firms_pkey PRIMARY KEY (id)
)
-- 2 300 000 rows
CREATE TABLE firms2branches
(
firm_id bigint NOT NULL,
branch_id bigint NOT NULL,
project_id bigint NOT NULL
)
CREATE INDEX firms2branches_firm_id_idx ON firms2branches USING btree(firm_id);
-- 6500 rows
CREATE TABLE accounts_premium
(
firm_id bigint NOT NULL,
is_active boolean NOT NULL DEFAULT false,
CONSTRAINT accounts_premium_pkey PRIMARY KEY (firm_id)
)
CREATE INDEX accounts_premium_is_active_idx ON accounts_premium USING btree(is_active);
查询(使用冷缓存):
EXPLAIN (ANALYZE)
SELECT firms2branches.branch_id,
firms2branches.firm_id
FROM firms2branches
JOIN firms ON firms.firm_id = firms2branches.firm_id
JOIN accounts_premium ON accounts_premium.firm_id = firms.id AND accounts_premium.is_active = TRUE
WHERE firms2branches.project_id = 21
结果(https://explain.depesz.com/s/oVNH):
Nested Loop (cost=22.12..6958.10 rows=355 width=16) (actual time=151.123..417.764 rows=31 loops=1)
Buffers: shared hit=7176 read=3371
-> Nested Loop (cost=21.69..3100.40 rows=1435 width=8) (actual time=0.905..58.314 rows=1378 loops=1)
Buffers: shared hit=3250 read=961
-> Bitmap Heap Scan on accounts_premium (cost=21.40..226.90 rows=1435 width=8) (actual time=0.615..1.211 rows=1378 loops=1)
Filter: is_active
Heap Blocks: exact=61
Buffers: shared hit=61 read=6
-> Bitmap Index Scan on accounts_premium_is_active_idx (cost=0.00..21.04 rows=1435 width=0) (actual time=0.594..0.594 rows=1435 loops=1)
Index Cond: (is_active = true)
Buffers: shared read=6
-> Index Scan using firms_pkey on firms (cost=0.29..1.90 rows=1 width=16) (actual time=0.040..0.041 rows=1 loops=1378)
Index Cond: (id = accounts_premium.firm_id)
Buffers: shared hit=3189 read=955
-> Index Scan using firms2branches_firm_id_idx on firms2branches (cost=0.43..2.59 rows=1 width=16) (actual time=0.259..0.260 rows=0 loops=1378)
Index Cond: (firm_id = firms.firm_id)
Filter: (project_id = 21::bigint)
Rows Removed by Filter: 2
Buffers: shared hit=3926 read=2410
Planning time: 6.164 ms
Execution time: 417.843 ms